氣泡排序 快速排序

2021-08-22 02:51:02 字數 2531 閱讀 2191

一、氣泡排序

【演算法步驟】以n個數排序,從小到大排為例說明。

(1)待排序數中,從第1個數開始,每個數與它後面的數比較,若逆序則交換。完成後則最大數排到最後,待排序數個數減少乙個。

(2)若待排序數個數為1,則它就是最小數,排在首位。否則,回到第(1)步。

具體講解如下:

第一趟:第1、2個數比較,若逆序則交換;第2、3個數比較,若逆序則交換;……;第n-1、n個數比較,若逆序則交換。

比較次數為n-1次。比較結束後,最大數排到第n位。

第二趟:第1、2個數比較,若逆序則交換;第2、3個數比較,若逆序則交換;……;第n-2、n-1個數比較,若逆序則交換。

比較次數為n-2次。比較結束後,第二大的數排到第n-1位。

第n-1趟:第1、2個數比較,若逆序則交換。

比較次數為1次。比較結束後,第二小的數排在第2位。

第一小的數不用再比較。氣泡排序結束。

【注意】1、共進行n-1趟。第一趟比較n-1次,第二趟比較n-2次,……第n-1趟比較1次。2、可能會發生相鄰元素間的交換。

【優化】引入布林變數no_sort=1,如果某趟有交換,則no_sort=0,否則no_sort=1,內迴圈結束後判斷no_sort是否為1,若為1,則退出外迴圈,否則,繼續外迴圈。

【穩定性】穩定

【時間複雜度】

1、沒有優化時為o(n^2)。

2、優化後:

最好情況下,待排序數已經按要求排好序,則只進行n-1次比較,不用交換,故時間複雜度為o(n)。

最壞情況下,待排序數剛好倒序,則要進行(n-1)+(n-2)+...+1=n*(n-1)/2次比較及交換,故時間複雜度為o(n^2)。

【示例**】

//氣泡排序(優化後)

void bubblesort(int a,int n)

if(no_sort)break;

} }

二、快速排序

【演算法步驟】以n個數排序,從小到大排為例說明。

(1)隨機選取乙個元素(通常取中間元素)作為樞軸或支點。

(2)將所有小於等於支點的元素放在左邊序列,所有大於等於支點的元素放在右邊序列。這樣完成一趟快速排序。

(3)繼續分別對這兩個子串行進行快速排序,直到整個序列有序。

具體做法如下:

(1)引入兩個指標i與j,分別指向待排序元素的首l與尾r。支點記為mid。

(2)i從左往右掃瞄,指向第乙個大於等於mid的元素。j從右往左掃瞄,指向第乙個小於等於mid的元素。交換這兩個元素。如果i<=j,則重複(2)。

(3)如果左子串行元素個數大於等於2,則對左序列進行快速排序。右序列同樣處理。如果元素個數為1個,則不用繼續快速排序。

【注意】1、這是對冒泡演算法的改進,採用了分治的思想。2、只關心支點的值,不用關心支點的位置。3、可能發生不相鄰元素間的交換,從而改變兩個相等元素的先後位置,所以快速排序是不穩定排序。

【穩定性】不穩定

【時間複雜度】平均為o(nlogn),最壞為o(n^2)。

平均情況下,每趟快排結束後,每次劃分使兩個子串行的長度大致相等,時間複雜度為o(nlogn)。

【證明】 已知t(n)=2t(n/2)+n

=2*(2t(n/4)+n/2)+n=2^2t(n/2^2)+2n

=2^2(2t(n/8)+n/4)+2n=2^3t(n/2^3)+3n

令n=2^m,則

t(n)=2^mt(1)+mn=2^lognt(1)+nlogn=n+nlogn=o(nlogn)

補充說明:遞迴logn層,每層比較o(n)次,故時間複雜度為o(nlogn)。

最壞情況下,是待排序記錄已經排好序。以每次快排都以第乙個待排序元素為支點為例說明:第一趟經過n-1次比較後第乙個記錄保持位置不變,並得到乙個n-1個元素的子串行;第二趟經過n-2次比較,將第二個記錄定位在原來的位置上,並得到乙個包括n-2個元素的子串行,依次類推,這樣總的比較次數是: (n-1)+(n-2)+…+1=n(n-1)/2,從而時間複雜度為o(n^2)。

【示例**】

下面兩種不同**有比較大的區別:

1、以中間位置元素為支點,將小於等於支點的數放在左邊序列,大於等於支點的數放在右邊序列。i與j是兩個哨兵,i從左往右, j從右往左,直到兩個哨兵錯過身,也就是說,兩個哨兵碰面了,也要作交換!

//快速排序,以中間位置元素為支點

void qsort(int l, int r)

}if(l2、以序列第乙個元素為支點。將小於支點的元素歸在左子串行,大於支點的元素歸在右子串行。支點不進入下一層遞迴。

//快速排序,以序列第乙個元素為支點

void qsort(int l, int r)

{ if(l>=r) return;

int i=l,j=r;

int key=a[i]; /*用陣列的第乙個記錄作為分割槽元素*/

while(i!=j){

while(i=key) j--; //從右向左掃瞄,找第乙個碼值小於key的記錄,並交換到a[i]

a[i]=a[j];

while(i1、

2、c++資訊學奧賽一本通

3、

排序 氣泡排序 快速排序

快速排序 氣泡排序就是自上向下依次對比兩個數字,若上面的數字大於下面的數字,則兩者交換,否則不交換。這樣每次迴圈結束,未排序的最大的數就到了最下面。如陣列前兩次迴圈過程如下 快速排序的核心是partition 函式,其功能如下所示 34的位置找到後,其將陣列分成兩部分,前一部分都比34小,後一部分都...

排序 氣泡排序 快速排序

1 基本思想 將第乙個記錄的關鍵字與第二個記錄的關鍵字比較,若為逆序,則將兩個記錄交換,再向後比較。關鍵字小的漂浮,關鍵字大的下沉。2 穩定性 演算法穩定。3 時間複雜度 o n 空間複雜度 o 1 4 實現 include define n 5 陣列長度上限 intmain printf 氣泡排序...

排序(氣泡排序 快速排序

關於排序的穩定性 在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中r i r j 且r i 在r j 之前,而在排序後的序列中,r i 仍在r j 之前,則稱這種排序演算法是穩定的 否則稱為不穩定的。一 氣泡排序 氣泡排序的基本思想 每次比較...