对单链表进行重排序

Posted fuqia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对单链表进行重排序相关的知识,希望对你有一定的参考价值。

要求:形式如L0->L1->L2->L3-> ... ->Ln-1->Ln,要求重新排序成如下形式:L0->Ln->L1->Ln-1->……
如给定链表为1->2->3->4->5->6,则重新排序后的结果为1->6->2->5->3->4

 思路:分为以下三步:   

  1. 寻找链表的中点,把链表分为两部分。如上面链表从3->4这个地方分开。   
  2. 把中点后面的部分倒序。如上面链表后半部分倒序为6->5->4。   
  3. 把前半部分跟后半部分重新组合。如上面链表按照两个部分一边一个元素的顺序组合结果为1->6->2->5->3->4,就得到了最终结果。
struct Node {
    int data;
    Node *next;
};

Node* searchMid(Node* head) {
    Node *fast = head, *slow = head, *preSlow = head;

    while (fast != NULL && fast->next != NULL) {
        preSlow = slow;

        fast = fast->next->next;
        slow = slow->next;
    }
    preSlow->next = NULL;
    return slow;
}

Node* reverse(Node* head){

    //返回反转链表的首元结点的地址
    if (head == NULL || head->next == NULL)
        return head;

    Node* newhead = reverse(head->next); // 先反转后面的链表
    head->next->next = head;//再将当前节点(head)设置为其然来后面节点(head->next)的后续节点
    head->next = NULL;
    return newhead; // 此处返回的newhead,永远指向反转后链表的首元节点,不随着回朔而变化。
}

void reOrder(Node* head) {
    if (head == NULL || head->next == NULL) 
        return;

    Node* cur2 = searchMid(head);
    cur2 = reverse(cur2);

    Node * cur1 = head->next;
    Node* temp = NULL;
    //合并两个链表L1,L2 其中L1的长度<=L2的长度,|L2的长度-L1的长度|<=1
    while (cur1!=NULL&&cur1->next!=NULL) {
        temp = cur1->next;
        cur1->next = cur2;
        cur1 = temp;

        temp = cur2->next;
        cur2->next = cur1;
        cur2 = temp;
    }
    if (cur1 == NULL) head->next = cur2;
    else cur1->next = cur2;
}

 

以上是关于对单链表进行重排序的主要内容,如果未能解决你的问题,请参考以下文章

为什么代码会重排序?

为什么代码会重排序?

什么是重排序

指令重排序导致的可见性问题

Java 并发编程指令重排序规范 ( happens-before 先行发生原则 )

按降序对单链表进行排序