按照左右半区的方式重新组合单链表

本文介绍了一种链表重组算法,将链表分为左右半区,并按L1-R1-L2-R2...的顺序重新排列。算法首先确定链表中间节点,然后将右半区插入左半区之间。适用于各种链表长度,包括奇数和偶数节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第二章中“按照左右半区的方式重新组合单链表”这一题目的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 }
View Code

 

注:

  转载请注明出处;

  转载请注明源思路来自于左程云老师的《程序员代码面试指南》。

转载于:https://www.cnblogs.com/PrimeLife/p/5453779.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值