本文參考
出自leetcode上的題庫 —— 排序鍊錶
排序問題
給定鍊錶的頭結點 head ,按公升序排列並返回排序後的鍊錶
示例1:
輸入:head = [4,2,1,3]
輸出:[1,2,3,4]
示例 2:
輸入:head = [-1,5,3,4,0]
輸出:[-1,0,3,4,5]
示例 3:
輸入:head =
輸出:解題思路
題幹非常容易理解,就是對單向鍊錶進行排序,和陣列不同的是,我們不能在排序過程中隨機訪問鍊錶中的每乙個元素,因此無法應用需要向左遍歷的排序方法,如快速排序。和快速排序具有相同時間複雜度$o(nlogn)$的歸併排序是個不錯的選擇,我們可以先通過快慢指標將常鍊錶分為前後兩個部分,然後遞迴呼叫排序函式,是十分容易理解的分治思想。最後的merge函式也同常規的歸併演算法類似。
歸併排序解法
class
listnode:
def __init__
(self
, val=0, next=none
):self
.val = val
self
.next: listnode = next
class
solution:
def
sort_list(self
, head: optional[listnode]) -> optional[listnode]:
# 空鍊錶或僅有乙個結點的鍊錶
if head is none or
head.next is none
:return
head
# 僅有兩個結點的鍊錶
if head.next.next is none
:if
head.val > head.next.val:
head.val, head.next.val = head.next.val, head.val
return
head
# 利用快慢指標將鍊錶分為兩個部分
slow = fast = head
while
fast.next and
fast.next.next:
slow = slow.next
fast = fast.next.next
front = head
back = slow.next
slow.next = none
# 分治
front = self
.sort_list(front)
back = self
.sort_list(back)
# 合併
return self
.merge(front, back)
def
merge(self
, front: listnode, back: listnode):
head = listnode()
curr = head
while
front and
back:
if front.val <= back.val:
curr.next = front
front = front.next
else
:curr.next = back
back = back.next
curr = curr.next
if front is none
:while
back:
curr.next = back
curr = curr.next
back = back.next
else
:while
front:
curr.next = front
curr = curr.next
front = front.next
return
head.next
鍊錶排序演算法
1 題目 對亂序的鍊錶進行排序,要求空間複雜度為常數。leetcode 148 中等 輸入 4 2 1 3 輸出 1 2 3 4 輸入 1 5 3 4 0 輸出 1 0 3 4 5 2 思路 對於這題我有兩種解法,一種是時間複雜度o n2 對於暴力解法,我們會將整個鍊錶分為 有序段 和 無序段 兩段...
演算法 鍊錶排序
sort a linked list in o n log n time using constant space complexity.example 1 example 2 歸併排序 首先將鍊錶從中部切分為兩個部分,不斷遞迴這個過程 遞迴回溯的時候將兩個鍊錶歸併為有序鍊錶 public list...
排序演算法 鍊錶實現
陣列的高效體現於隨機訪問,插排 快排等排序演算法未用到這一特點,故這兩種排序演算法可基於鍊錶實現 插入排序 迭代器 p順序訪問鍊錶 迭代器 i順序訪問前 p 個元素 主要的操作為 當p i p.value刪除原位置的 p將p插入 i 1 與 i 之間 若為單向鍊錶,儲存 i 1與 p 1 演算法複雜...