【说明】:
本文是左程云老师所著的《程序员面试代码指南》第二章中“按照左右半区的方式重新组合单链表”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
给定一个单链表的头节点 head,链表长度为 N,如果 N 为偶数那么前 N/2 个节点算作左半区,后 N/2 个节点算作右半区;如果 N 为奇数,那么前 N/2 个节点算作左半区,后 N/2+1 个节点算作右半区。左半区从左到右依次记为 L1->L2->...,右半区从左到右依次记为 R1->R2->...,请将链表调整为 L1->R1->L2->R2->...的形式。
例如:
1->NULL,调整为1->NULL
1->2->NULL,调整为1->2->NULL
1->2->3->NULL,调整为1->2->3NULL
1->2->3->4->NULL,调整为1->3->2->4NULL
1->2->3->4->5->NULL,调整为1->3->2->4->5->NULL
1->2->3->4->5->6->NULL,调整为1->4->2->5->3->6->NULL
【思路】:
解法:正确的确定中间位置。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
实现及测试代码:
1 /* 2 *文件名:list_relocate.cpp 3 *作者: 4 *摘要:按照左右半区的方式重新组合单链表 5 */ 6 7 #include <iostream> 8 9 using namespace std; 10 11 class Node 12 { 13 public: 14 Node(int data) 15 { 16 value = data; 17 next = NULL; 18 } 19 public: 20 int value; 21 Node *next; 22 }; 23 24 void mergeLR(Node *left,Node *right) 25 { 26 Node *next = NULL; 27 while(NULL != left->next) //将right插入到left中 28 { 29 next = right->next; 30 right->next = left->next; 31 left->next = right; 32 left = right->next; 33 right = next; 34 } 35 left->next = right; 36 } 37 38 void relocate(Node *head) 39 { 40 if(NULL == head || NULL == head->next) 41 return ; 42 Node *mid = head; 43 Node *right = head->next; 44 while(NULL != right->next && NULL != right->next->next) //确定中心 45 { 46 mid = mid->next; 47 right = right->next->next; 48 } 49 right = mid->next; 50 mid->next = NULL; 51 mergeLR(head,right); 52 } 53 54 void printList(Node *head) 55 { 56 while(NULL != head) 57 { 58 cout << head->value << " "; 59 head = head->next; 60 } 61 cout << endl; 62 } 63 64 int main() 65 { 66 Node *head(NULL),*ptr(NULL); 67 for(int i =1;i<10;i++)//构造链表 68 { 69 if(NULL == head) 70 { 71 head = new Node(i); 72 ptr = head; 73 continue; 74 } 75 ptr->next = new Node(i); 76 ptr = ptr->next; 77 } 78 cout << "Before being relocated:" << endl; 79 printList(head); 80 cout << "After being relocated:" << endl; 81 relocate(head); 82 printList(head); 83 return 0; 84 }
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。