力扣 148排序鍊錶 筆記(歸併排序)

2021-10-10 17:07:01 字數 2753 閱讀 4573

題目:

因為時間複雜度要求(n*logn),所以考慮歸併排序(但歸併排序並不滿足常數級的空間複雜度,還需要使用快慢指標?)。

歸併排序:

把乙個待排序列從中間分兩半,每半再各自應用歸併排序處理。分出來的左右兩半的歸併操作中,同樣也是先把每半序列再從中間劈開,分成兩個子串行,再應用歸併排序,以此類推,由此看是乙個遞迴操作。

因此由此看來是,在每次歸併函式呼叫中,先檢測傳進來的序列長度,如果序列中只有1個元素,則排不了序直接return返回。如果序列中的元素多於1個,則先把它從中間劈開,分出來的左右兩個序列先各自呼叫歸併排序,然後各自的歸併排序完成之後,再把左右兩個序列的所有元素合一起,來乙個排序,這樣排完,一次完整的歸併函式的主要操作就完成了。

快慢指標參考:

當我們直接在鍊錶原地進行排序的時候,空間複雜的即為常數級。

用序列0、3、5、2、7、1、9、8測試

debug的時候,發現5、2這組從mergesort()回傳的時候,2給丟了,只有5。

原因是這句話:

mergesort

(a);

mergesort

(slow)

;return

merge

(a, slow)

;

如果裡面的兩個mergesort()呼叫單獨拿出來寫成兩句話的話,必須要有兩個變數接著他們返回來的值,否則a和slow依然指著自己在呼叫mergesort()前的兩個原結構體,即是鍊錶被排序了他倆也還指著原來兩個結構體,之後再呼叫merge(a, slow)的話這個呼叫邏輯就出錯了。

所以要麼寫成這樣:

a =

mergesort

(a);

slow =

mergesort

(slow)

;return

merge

(a, slow)

;

要麼寫成這樣:

return

merge

(mergesort

(a),

mergesort

(slow)

);

原始碼:

#include

struct listnode // 鍊錶節點定義

listnode

(int x)

:val

(x),

next

(nullptr

)listnode

(int x, listnode *next)

:val

(x),

next

(next)};

void

dis_listnode

(listnode *head)

std::cout << std::endl;

}class

solution

;listnode* solution::

sortlist

(listnode *a)

listnode *fast,

*slow,

*pre;

// 先用快慢指標找到鍊錶a的中間節點,把a劈兩半,pre在while結束後最終指向左半部分的最後乙個節點

pre = fast = slow = a;

while

(fast && fast-

>next)

pre-

>next =

null

;return

merge

(sortlist

(a),

sortlist

(slow));

}listnode* solution::

merge

(listnode *left, listnode *right)

else

listnode *p = head;

// 開始排序,left和right誰小就往後接

while

(left && right)

else

}while

(left)

while

(right)

p->next =

nullptr

;dis_listnode

(head)

;return head;

}int

main()

; listnode *p =

newlistnode

(val[i--],

nullptr);

for(

; i >=0;

--i)

listnode *head = p;

std::cout <<

"待排鍊錶中的元素:"

;dis_listnode

(head)

;// 歸併排序

solution *solution =

new solution;

head = solution-

>

sortlist

(head)

; std::cout <<

"排序後的序列:"

;dis_listnode

(head)

;return0;

}

148 排序鍊錶 歸併排序

難度 中等 題目描述 解題思路 148.排序鍊錶 2020 8 13 1對鍊錶進行歸併排序 1 快慢指標找中間節點 2 遞迴呼叫mergesort 3 合併有序鍊錶 public listnode sortlist listnode head public listnode listmergesor...

力扣 148 排序鍊錶

傳送門 題目分析 題目要求時間複雜度為 o nlogn 空間複雜度為 o 1 根據時間複雜度,我們自然能想到二分,故這裡要用到歸併排序。對鍊錶的排序,可以通過修改指標來更改節點順序,無需像陣列一樣額外開闢儲存空間。歸併排序有遞迴和非遞迴的做法,這裡採用遞迴的做法。首先,講一下什麼是歸併排序?歸併排序...

力扣 148 排序鍊錶

給你鍊錶的頭結點 head 請將其按 公升序 排列並返回 排序後的鍊錶 高階 你可以在 o n log n 時間複雜度和常數級空間複雜度下,對鍊錶進行排序嗎?示例 1 輸入 head 4,2,1,3 輸出 1,2,3,4 示例 2 輸入 head 1,5,3,4,0 輸出 1,0,3,4,5 示例 ...