對單鏈表進行重排序

要求:形式如L0->L1->L2->L3-> ... ->Ln-1->Ln,要求從新排序成以下形式:L0->Ln->L1->Ln-1->……
如給定鏈表爲1->2->3->4->5->6,則從新排序後的結果爲1->6->2->5->3->4

 思路:分爲如下三步:   spa

  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;
}
相關文章
相關標籤/搜索