詳談內部排序之快速排序

2021-10-07 21:30:35 字數 3552 閱讀 1252

交換排序:

​ 兩兩比較待排序記錄的關鍵碼,如果發生逆序(即排列順序與排序後的次序正好相反),則交換之,直到所有記錄都排好序為止 。

​ 交換排序的主要演算法有:

​ (1) 氣泡排序

​ (2) 快速排序

快速排序基本思想:

(1) 基本思想:

​ 通過一趟排序將待排序列以樞軸為標準劃分成兩部分,使其中一部分記錄的關鍵字均比另一部分小,再分別對這兩部分進行快速排序,以達到整個序列有序。

​ 通常取第乙個記錄的值為基準值或樞軸。

(2) 具體做法:

​ 附設兩個指標low和high,初值分別指向第乙個記錄和最後乙個記錄,設樞軸為key;

​ 1.從high 所指位置起向前搜尋,找到第乙個不大於基準值的記錄與樞軸記錄相互交換;

​ 2.從low 所指位置起向後搜尋,找到第乙個不小於基準值的記錄與樞軸記錄相互交換。

​ 3.重複這兩步直至為止。

例:以關鍵字序列(256,301,751,129,937,863,742,694,076,438)為例

​ 寫出執行快速演算法的各趟排序結束時,關鍵字序列的狀態。

初始佇列

256301

751129

937863

742694

076438

第一趟【076

129】

256【751

937863

742694

301438】

第二趟076

129256

【438

301694

742】

751【863

937】

第三趟076

129256

438【694

742】

751863

937第四趟

076129

256301

438694

742751

863937

詳細講解:

​ 首先我們預設每一組資料的樞軸為它第乙個元素。即將初始佇列中的第乙個元素:256設定為樞軸。

​ 我們這裡將,low或high的值改變到其他位置後,將low或high設為0,以方便辨別每一步步驟。

第一趟:

將low = 256,high = 438,key = 256;

先從high處開始:

① key < high ,所以位置不變,將 high- - 得:low = 256,high = 076

② key > high ,所以交換位置,將 low= high,同時將high處的值設為0得:low = 076,high = 0

即:076301 751 129 937 863 742 6940438

當high的位置改變後,再從low處開始:

③ key > low ,所以位置不變,將 low = 301,high = 0

④ key < low ,所以交換位置,將 low = 0,high = 301

即:0760751 129 937 863 742 694 **301 ** 438

當low的位置改變後,再從high處開始:

⑤ key < high ,所以位置不變,low = 0,high = 694

⑥ key < high ,所以位置不變,low = 0,high = 742

⑦ key < high ,所以位置不變,low = 0,high = 863

⑧ key < high ,所以位置不變,low = 0,high = 937

⑨ key < high ,所以位置不變,low = 0,high = 129

⑩ key > high ,所以交換位置,low = 129,high = 0

即:0761297510937 863 742 694 301 438

當high的位置改變後,再從low處開始:

⑪ key > low ,所以位置不變,low = 751,high = 0

⑫key < low ,所以交換位置,low = 0 ,high = 751

076 1290751937 863 742 694 301 438

當low和high都搜算到乙個位置的時候,說明第一趟查詢結束,所以將low和high所指的地方賦值為key=256;

得到 076 129 256 751 937 863 742 694 301 438

由上可知:

樞軸256左邊的都是小於256的,在樞軸256右邊的都是大於256的。

之後再將左邊和右邊分為兩個序列,分別進行如上的快速排序步驟。

之後的步驟只需重複上面的步驟,直到全部排列完成。

int partition (elem r[ ], int low, int high) 

r[low] = r[0]; //樞軸記錄到位

return low; //返回樞軸位置

}

void qsort ( elem r[ ], int low, int high )

} void quicksort(elem r, int n)

​ •可以證明,函式quicksort的平均計算時間是o(nlog2n)。實驗結果表明:就平均計算時間而言,快速排序是我們所討論的所有內排序方法中最好的乙個。

​ •快速排序是遞迴的,需要有乙個棧存放每層遞迴呼叫時的指標和引數(新的low和high)。最大遞迴呼叫層次數與遞迴樹的深度一致,理想情況為

•最好情況:

​ 如果每次劃分對乙個物件定位後,該物件的左側子串行與右側子串行的長度相同,則下一步將是對兩個長度減半的子串行進行排序,這是最理想的情況。此時,快速排序的趟數最少。

•最壞情況:

​ 即待排序物件序列已經按其關鍵碼從小到大排好序的情況下,其遞迴樹成為單支樹,每次劃分只得到乙個比上一次少乙個物件的子串行。這樣,必須經過 n-1 趟才能把所有物件定位,而且第 i 趟需要經過 n-i 次關鍵碼比較才能找到第 i 個物件的安放位置,總的關鍵碼比較次數將達到n^2/2

時間效率:o(nlog2n) —因為每趟確定的元素呈指數增加

空間效率:o(log2n)—因為演算法的遞迴性,要用到棧空間

穩 定 性:不穩定 —因為可選任一元素為支點。

答:——基本上是!因為每趟可以確定的資料元素是呈指數增加的!

設每個子表的支點都在中間(比較均衡),則:

第1趟比較,可以確定1個元素的位置;

第2趟比較(2個子表),可以再確定2個元素的位置;

第3趟比較(4個子表),可以再確定4個元素的位置;

第4趟比較(8個子表),可以再確定8個元素的位置;

綜上只需 ( └ log2n ┘ + 1 ) 趟便可排好序。

​ 而且,每趟需要比較和移動的元素也呈指數下降,加上程式設計時使用了交替逼近技巧,更進一步減少了移動次數,所以速度特別快。

詳談內部排序之各種插入排序

如上圖的插入撲克牌就是生活中最常見的插入排序。直接插入排列過程 先將序列中第 1 個記錄看成是乙個有序子串行,然後從第 2 個記錄開始,逐個進行插入,直至整個序列有序。例題 為直接插入排序的詳細過程,其中有一些注意事項 1 資料中有兩個49,其中乙個加粗,用來判斷這兩個49的前後順序是否發生變化,然...

內部排序之 快速排序

本文整理我對快速排序的學習與理解。時間複雜度好的情況下o n logn 最壞的情況下o n n 對於一組序列 a 1 選擇第乙個元素作為分界值temp,比temp大的數往右移,比temp小的數往左移,分為兩類 2 把temp移到中間,其左右兩個區間看做新的待排序的序列,重複第1步。這是乙個遞迴過程,...

內部排序 交換類排序 快速排序

在氣泡排序中,由於掃瞄過程中只對相鄰的兩個元素進行比較,因此在互換兩個相鄰元素時只能消除乙個逆序,如果能通過兩個 不相鄰的 元素的交換,消除待排序記錄中的多個逆序則會大大加快排序的速度。快速排序方法中的一次交換可以消除多個逆序。演算法思想 從待排序記錄序列中選取乙個記錄 通常選取第乙個記錄 為樞軸,...