高效鍊錶排序 歸併演算法

2021-07-11 13:48:31 字數 2439 閱讀 4535

排序演算法應該是最基礎的了,快速、歸併、選擇、堆排序等等

對於陣列而言可以隨機訪問,那麼對於鍊錶呢,比如快排,兩個指標分別網後往前走,而沒有前驅指標的單向鍊錶,無法完成這樣的操作,當然了可以採用快慢指標的方式,在提交leetcode的時候,發現快排是會超時的。

那麼對於鍊錶而言,可以採取一種怎麼樣的高效排序演算法呢

歸併排序

分而治之,分別拍好前後兩個部分,然後合併兩個有序鍊錶,在合適不過,並且由於鍊錶自帶屬性,合併鍊錶還無需0(n)額外的空間,因此歸併排序成為鍊錶排序的首選。

我一直認為歸併排序是挺好理解的,也比較簡單,但是看了看網上的部落格,為什麼總感覺要麼是放一堆**,要麼放一堆很長很長的**,不如自己寫個簡單點的,完全按照陣列的方式。

歸併排序有幾個子問題,鍊錶分割有序鍊錶合併

鍊錶分割

將乙個鍊錶分為為兩個長度相等的鍊錶(單數時會多乙個)。

這個問題就相當於找到鍊錶的中點,很簡單的使用快慢指標,快指標走到尾節點,慢指標剛好走到一半。

第乙個鍊錶的頭為head,第二個鍊錶的頭為慢指標的next指標。先拍後面,在拍前面。

此時需要注意,鍊錶要分成兩份,從中間斷開,因此需要將慢節點的next指標設定為null很關鍵!!!。

listnode* sort_list(listnode *head)

if (r == head)//如果此時只有兩個節點,那麼中間節點就是頭節點,l=r=head,無限迴圈,因此特殊判斷

r=sort_list(l->next);//排序後半部分

l->next =

null;//注意,一定要把前面從中間節點切斷

l=sort_list(head);//排序前面一部分

listnode* temp = merge_list(l, r);//合併兩個有序鍊錶

return temp;

}

有序鍊錶合併類似於合併有序陣列,不過不需要額外的空間了。

比如 鍊錶1 1->3->7->9

鍊錶2 2->4->10->29

由於需要返回乙個新的頭部,而頭部必然為鍊錶1的頭部或鍊錶2的頭部,因此不需要另外新建了。

**如下

listnode * merge_list(listnode *head1, listnode *head2)

else

p = newhead;

while (head1 !=

null

&& head2 !=

null)

else

}while (head1 !=

null)

while (head2 !=

null)

p->next =

null;

return newhead;

}

然後就是乙個遞迴呼叫的過程

完整測試**

struct listnode 

};class solution

else

p = newhead;

while (head1 !=

null

&& head2 !=

null)

else

}while (head1 !=

null)

while (head2 !=

null)

p->next =

null;

return newhead;

}listnode* sort_list(listnode *head)

if (r == head)//如果此時只有兩個節點,那麼中間節點就是頭節點,l=r=head,無限迴圈,因此特殊判斷

r=sort_list(l->next);//排序後半部分

l->next =

null;//注意,一定要把前面從中間節點切斷

l=sort_list(head);//排序前面一部分

listnode* temp = merge_list(l, r);//合併兩個有序鍊錶

鍊錶排序 歸併

遞迴方法的歸併排序三部曲 1,快慢指標找中點 2,遞迴呼叫mergesort,3,合併兩個鍊錶。class solution listnode mergesort listnode node breakn next nullptr listnode l1 mergesort node listnod...

演算法 鍊錶的歸併排序

複雜度分析 設定兩個指標,乙個步長為1,乙個步長為2,當快指標到達尾結點時,慢指標指向中間結點,時間複雜度為o n 平分為左鍊錶l1和右鍊錶l2,遞迴 直到鍊錶為空或者只有乙個結點 將鍊錶l2的每個結點插入到鍊錶l1中,時間複雜度為o m n m n分別為兩條鍊錶的長度。畫出遞迴樹,可知總的時間複雜...

鍊錶排序 歸併排序

要求在空間複雜度為o 1 的情況下對鍊錶進行排序,在不考慮時間複雜度的情況下可以考慮氣泡排序,只對鍊錶中的值進行操作,這樣時間複雜度為o n 2 用歸併排序,時間複雜度為o nlogn 以下為歸併排序 實現 public listnode sortlist listnode head private...