最近刷leetcode時遇到了兩道鍊錶排序題,相對陣列排序而言處理上覆雜了一些,卻蠻有意思。有必要記錄一下。
leetcode第147題對鍊錶進行插入排序並不複雜,相對於陣列的插入排序來說思路是直接可以用的。首先我們設定乙個dummy頭節點,然後從待排序煉表裡依次拿出節點,放入dummy煉表裡的合適位置即可。p1和p2是用於尋找合適插入位置的兩個指標。演算法複雜度o(n
2)
o(n^2)
o(n2)。
/**
* definition for singly-linked list.
* struct listnode
* };
*/class
solution
p1->next = tem;
tem-
>next = p2;
}return dummy-
>next;}}
;
leetcode第148題也是一道鍊錶排序題,但是上一題的**在此題不能通過,時間複雜度要求為o(n
long
n)
o(nlongn)
o(nlon
gn),所以需要歸併排序。事實上同陣列的歸併排序相比,鍊錶的歸併排序要解決兩個問題,一是如何找到鍊錶的中點,二是如何讓兩個有序鍊錶合併在一起。
對於第乙個問題,可以使用快慢指標的做法。使用兩個指標slow和fast初始化為頭節點和頭節點的下乙個節點,每次讓slow走一步,fast走兩步,直到fast到達尾部。第二個問題請參考leetcode21題,這是乙個基礎問題,這裡就不多贅述了。剩下的思路和陣列歸併排序差不多。
/**
* definition for singly-linked list.
* struct listnode
* listnode(int x) : val(x), next(nullptr) {}
* listnode(int x, listnode *next) : val(x), next(next) {}
* };
*/class
solution
listnode*
mergesort
(listnode* head)
listnode* tem = slow-
>next;
slow-
>next =
nullptr
; listnode* left =
mergesort
(head)
; listnode* right =
mergesort
(tem)
;return
merge
(left,right);}
listnode*
merge
(listnode* l1,listnode* l2)
else}if
(l1)
tail-
>next = l1;
else
tail-
>next = l2;
listnode* tem = dummy-
>next;
delete dummy;
return tem;}}
;
鍊錶的歸併排序,插入排序
來自資料結構與演算法書 進行鍊錶排序並避免建立,刪除新的節點 1.node是結構體模板,linklist是類模板 using namespace std template struct node template class linklist 2 歸併排序 template void linklis...
插入排序和歸併排序實現
在文章 的基礎上,利用c 中的vector容器代替陣列來實現,但是發現這樣做大大的增加了程式執行的時間,並且兩者的執行時間幾乎差不多 改寫的程式 include include include stdio.h include include using namespace std 插入排序 vect...
插入排序和歸併排序
一共有三種 直接插入排序 希爾排序和折半插入排序。最後乙個折半插入排序,感覺用在陣列上面不太方便,就沒寫出來。遞迴實現沒有思路,使用的非遞迴演算法。直接插入排序 這個演算法預設前n個數是已經排好序的,n隨著你的插入逐漸變大,最開始是1。然後從後往前逐漸查詢應該插入的位置 我的演算法是從小到大,那就依...