接上篇,繼續介紹歸併排序與快速排序。
歸併排序使用的是分治策略,核心思想也比較簡單。要排序乙個序列,首先從中間將序列一分為二,然後對劃分的前後兩個序列進行排序,再將排序好的序列合而為一,這樣原有的序列就已有序了。
可見,歸併排序的核心在於合併有序序列。以下圖為例,有兩個待合併有序序列 5, 6, 8, 9, 與 2, 3, 4, 7。依次比較兩序列中待確認的最小元素。首先,比較2與5,2比5小,2確認為序列第乙個元素;比較3與5,3比5小,3確認為序列第二個元素;以此類推,直至7與8比較,7比8小,7確認為序列中元素,此時第二個序列為空,只需將第乙個序列中元素按次序放入新序列中即可。
**簡單示例如下:
public
void
mergesort
(int
a,int lo,
int hi)
int mi =
(lo + hi)
>>1;
mergesort
(a, lo, mi)
;mergesort
(a, mi, hi)
;merge
(a, lo, mi, hi);}
public
void
merge
(int
a,int lo,
int mi,
int hi)
for(
int i = lo, j =
0, k = mi;
(j < ls || k < hi);)
if(k < hi &&
(ls <= j || a[k]
< b[j]))
}}
假設對n個元素進行排序需要時間為t(n),則t(n) = 2 * t(n/2) + n,簡單計算後可得歸併排序時間複雜度為o(logn)。
歸併排序是穩定排序演算法,由merge方法中序列合併時處理決定。但是由於在合併過程中需新建陣列作為臨時儲存空間,因此歸併排序並不是原地演算法。事實上,額外需要的空間最大不會超過序列本身大小,故歸併排序的空間複雜度為o(n)。
與歸併排序相同,快速排序也是使用分治策略,而與歸併排序不同的是,快速排序的關鍵點在於分解,而歸併排序的關鍵點在於合併。基本思路是:
在待排序列中找到乙個軸點pivot;
遍歷所有元素,將值大於pivot的元素放到右側,小於pivot的元素放到左側,等於pivot的元素放至中間;
接著對左右序列分別回到1步驟,直至序列區間縮小為1。
之前提到,快速排序的關鍵點在於分解,分解的方式有許多種,此處介紹較簡單的一種方式。如下圖,首先,此處取第乙個元素為軸點,lo=0,hi=7,從序列末端開始。3<8,將3複製至lo處,lo加一,接著從lo處開始遞增檢查至9處,發現9>8,將9複製至hi處,hi減一,接著從hi處開始遞減檢查至7處,發現7<8,將7複製至lo處,lo加一,接著再次從lo處開始遞增檢查至hi處,遍歷結束,將pivot賦值至lo處。此時,lo左側元素均小於pivot,hi右側元素均大於pivot。
**簡單示例如下:
public
void
quicksort
(int
a,int lo,
int hi)
int mi =
partition
(a, lo, hi -1)
;quicksort
(a, lo, mi)
;quicksort
(a, mi +
1, hi);}
public
intpartition
(int
a,int lo,
int hi)
a[lo]
= a[hi]
;while
(lo < hi && a[lo]
<= pivot)
a[hi]
= a[lo];}
a[lo]
= pivot;
return lo;
}
快速排序的時間複雜度取決於pivot的選擇。軸點的選擇很重要。一般可選擇起點或終點作為軸點,但可能由於序列分布特殊導致時間複雜度變化很大。可以採取隨機選取或三點取中位數等方式減小最壞情況出現的概率。最好情況下,每次劃分接近平均,即t(n) = 2 * t((n- 1)/ 2)+ n = o(logn)。最壞情況下,每次劃分都很不均衡,即t(n) = t(n - 1) + t(0) + n = o(n^2)。平均情況下分析方式類似,為o(logn)。
快速排序是原地排序演算法,但不是穩定的。
另外,關於快排演算法,還有許多變種,後續有空細提。
資料結構與演算法小結 排序(二)
1.2 希爾排序 希爾排序屬於插入排序的一種,是直接插入排序的優化,其主要思想是 由於在序列基本有序的情況下,直接插入排序的效率很高,那麼,我們引入乙個增量incre,把以incre為間隔的元素做一次直接插入排序,使其基本有序 隨後,incre慢慢減小,繼續做上述直接插入排序,最後incre變成1,...
資料結構與演算法 排序
排序原理 1.比較相鄰的元素。如果前乙個元素比後乙個元素大,就交換這兩個元素的位置。2.對每一對相鄰元素做同樣的工作,從開始第一對元素到結尾的最後一對元素。最終最後位置的元素就是最大 值。氣泡排序的 實現 public static void sortpop int arr 測試 public st...
《資料結構與演算法 排序》
1 快速排序 1.記錄 排序中的結點 2.檔案 一系列結點構成的線性表 3.排序又稱分類 4.排序碼 結點中乙個或者多個字段,其值作為排序運算中的根據。基本思想 每次選擇待排序的記錄序列的第1個記錄,按照排序碼的大小將其插入到已排序的記錄序列的適當位置,直到所有記錄全部排序完畢。最簡單的排序方法。整...