資料結構與演算法 排序(歸併和快排)

2021-10-25 01:43:40 字數 2064 閱讀 5632

快速排序原理

歸併排序和快速排序的區別

歸併排序的核心思想還是蠻簡單的。如果要排序乙個陣列,我們先把陣列從中間分成前後兩部分,然後對前後兩部分分別排序,再將排好序的兩部分合併在一起,這樣整個陣列就都有序了。

歸併排序使用的就是分治思想。分治,顧名思義,就是分而治之,將乙個大問題分解成小的子問題來解決。小的子問題解決了,大問題也就解決了。

遞推公式:

merge_sort

(p…r)

=merge

(merge_sort

(p…q)

,merge_sort

(q+1…r)

)終止條件:

p >= r 不用再繼續分解

偽**

// 歸併排序演算法, a是陣列,n表示陣列大小

merge_sort

(a, n)

// 遞迴呼叫函式

merge_sort_c

(a, p, r)

下圖演示的是乙個merge的過程

merge() 合併函式如果借助哨兵,**就會簡潔很多,**如何實現???

快排的思想是這樣的:如果要排序陣列中下標從 p 到 r 之間的一組資料,我們選擇 p 到 r 之間的任意乙個資料作為 pivot(分割槽點)。

遞推公式:

quick_sort

(p…r)

=quick_sort

(p…q-1)

+quick_sort

(q+1… r)

終止條件:

p >= r

偽**

// 快速排序,a是陣列,n表示陣列的大小

quick_sort

(a, n)

// 快速排序遞迴函式,p,r為下標

quick_sort_c

(a, p, r)

將小於 pivot 的元素都拷貝到臨時陣列 x,將大於 pivot 的元素都拷貝到臨時陣列 y,最後再將陣列 x 和陣列 y 中資料順序拷貝到 a[p…r]。

由上圖可以看到分割槽好函式需要臨時申請空間,所以不是原地排序演算法,要想成為原地排序,那麼分割槽操作就要在原地完成。

原地分割槽偽**的實現

可以發現,歸併排序的處理過程是由下到上的,先處理子問題,然後再合併。而快排正好相反,它的處理過程是由上到下的,先分割槽,然後再處理子問題。歸併排序雖然是穩定的、時間複雜度為 o(nlogn) 的排序演算法,但是它是非原地排序演算法。我們前面講過,歸併之所以是非原地排序演算法,主要原因是合併函式無法在原地執行。快速排序通過設計巧妙的原地分割槽函式,可以實現原地排序,解決了歸併排序占用太多記憶體的問題。

演算法整理 排序(歸併和快排)

趁找工作之際,著手對演算法進行相關學習和整理,便於自己複習鞏固,也以此來督促自己進行演算法的研究學習。通過對演算法的整理,一方面希望對於自己有所提高,另一方面,也希望提高自己的書面表達能力,文中有所不正確的地方,望批評指出,多謝。對於演算法學習,從簡單到複雜。今天主要整理一下排序相關的演算法。對於排...

資料結構與演算法 排序演算法 (堆排 快排 歸併)

快排的時間複雜度是o nlogn 其實現思想就是隨機找到乙個中間值 小於這個值得放左邊 大於這個值得放右邊 然後大於這個值得半部分和小於這個值得半部分分別遞迴 直到全部排完 jdk1.8中的arrays.sort 的排序方法就是使用的快排 當資料量大於47的時候採用快排 小於47的時候使用插排 實現...

排序演算法詳解 選擇 插入 歸併和快排

特點 每次從待排序序列中選取最小值最為當前元素值 流程 已排好序的陣列為a 0,i 1 將未排序序列a i,n 中最小值賦給a i const int maxn 10000 int a maxn void selectsort int a,int n 特點 將未排序元素插入到已排序元素的合適位置上 ...