交換排序 氣泡排序和快速排序

2021-06-20 09:24:08 字數 3056 閱讀 6244

1、氣泡排序演算法思想及實現

這是最原始,也是眾所周知的最慢的演算法了。

基本思想:

按待排序序列的先後順序,依次比較相鄰的兩個數,將小數放在前面,大數放在後面(若二者是公升序,則不作任何操作,否則交換兩個數即可)。即在第一趟:首先比較第1個數和第2個數,將小數放前面,大數放後面。然後比較第2個數和第3個數,將小數放前面,大數放後面,如此繼續,直至比較最後兩個數,將小數放前面,大數放後面。至此第一趟排序結束,最大的數在最後的位置。在第二趟:仍從第一對數開始比較(因為可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前面,大數放後面,一直比較到倒數第二個數(倒數第一的位置上已經是最大的), 第二趟結束,在倒數第二的位置上得到乙個新的最大數(其實在整個數列中是第二大的數)。如此下去,重複以上過程,直至最終完成排序。由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上公升,因此稱作氣泡排序。

#include using namespace std;

void bubble_sort(int *pdata,int count)

} }}void main()

; bubble_sort(data,7);

for (int i=0;i <7; i++)

cout << data << " ";

cout << "\n";

}

倒序(最糟情況) 

第一輪:10,9,8,7,6,5,4->9,10,8,7,6,5,4->9,8,10,7,6,5,4->9,8,7,10,6,5,4->9,8,7,6,10,5,4->9,8,7,6,5,10,4->9,8,7,6,5,4,10(交換6次) 

第二輪:9,8,7,6,5,4->8,9,7,6,5,4->8,7,9,6,5,4->8,7,6,9,5,4->8,7,6,5,9,4->8,7,6,5,4,9(交換5次) 

第三輪:8,7,6,5,4->7,8,6,5,4->7,6,8,5,4->7,6,5,8,4->7,6,5,4,8(交換4次)

第四輪:7,6,5,4->6,7,5,4->6,5,7,4->6,5,4,7(交換3次)

第五輪:6,5,4->5,6,4->5,4,6(交換2次)

第六輪:5,4->4,5(交換1次)

迴圈次數:6次

交換次數:21次

上面我們給出了程式段,現在我們分析它:這裡,影響我們演算法效能的主要部分是迴圈和交換, 

顯然,次數越多,效能就越差。從上面的程式我們可以看出迴圈的次數是固定的,為1 2 ... n-1。 

寫成公式就是1/2*(n-1)*n。 

現在注意,我們給出o方法的定義: 

若存在一常量k和起點n0,使當n>=n0時,有f(n)<=k*g(n),則f(n) = o(g(n))。

現在我們來看1/2*(n-1)*n,當k=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=k*g(n)。所以f(n) 

=o(g(n))=o(n*n)。所以我們程式迴圈的複雜度為o(n*n)。

[演算法思想]:將被排序的記錄陣列r[1..n]垂直排列,每個記錄r[i]看作是重量為 r[i].key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r:凡掃瞄到違反本原則的輕氣泡,就使其向上"飄浮"。如此反覆進行,直到 最後任何兩個氣泡都是輕者在上,重者在下為止。

[演算法]:

void bubblesort(seqlist r) 

} while (i <= j) ; //如果兩邊掃瞄的下標交錯,就停止(完成一次)

//當左邊部分有值(lefti),遞迴右半邊

if(right>i)

quicksort (pdata,i,right);

}

對於n個成員,快速排序法的比較次數大約為n*logn 次,交換次數大約為(n*logn)/6次。如果n為100,冒泡法需要進行4950 次比較,而快速排序法僅需要200 次,快速排序法的效率的確很高。快速排序法的效能與中間值的選定關係密切,如果每一次選擇的中間值都是最大值(或最小值),該演算法的速度就會大大下降。快 速排序演算法最壞情況下的時間複雜度為o(n2),而平均時間複雜度為o(n*logn)。

【演算法思想】

快速排序是c.r.a.hoare於2023年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(divide-and-conquermethod)。

分治法的基本思想

:分治法的基本思想是:將原問題分解為若干個規模更小但結構與原問題相似的子問題。遞迴地解這些子問題,然後將這些子問題的解組合為原問題的解。

快速排序的基本思想

:設當前待排序的無序區為r[low..high],利用分治法可將快速排序的基本思想描述為:

分解:在r[low..high]中任選乙個記錄作為基準(pivot),以此基準將當前無序區劃分為左、右兩個較小的子區間r[low..pivotpos-1)和r[pivotpos+1..high],並使左邊子區間中所有記錄的關鍵字均小於等於基準記錄(不妨記為pivot)的關鍵字pivot.key,右邊的子區間中所有記錄的關鍵字均大於等於pivot.key,而基準記錄pivot則位於正確的位置(pivotpos)上,它無須參加後續的排序。

注意:劃分的關鍵是要求出基準記錄所在的位置pivotpos。劃分的結果可以簡單地表示為(注意pivot=r[pivotpos]):

r[low..pivotpos-1].keys≤r[pivotpos].key≤r[pivotpos+1..high].keys    其中low≤pivotpos≤high。

求解:通過遞迴呼叫快速排序對左、右子區間r[low..pivotpos-1]和r[pivotpos+1..high]快速排序。

組合:因為當"求解"步驟中的兩個遞迴呼叫結束時,其左、右兩個子區間已有序。對快速排序而言,"組合"步驟無須做什麼,可看作是空操作。

【快速排序演算法quicksort】

void quicksort(seqlist r,int low,int high)

//endwhile

r[i]=pivot; //基準記錄已被最後定位

return i;

} //partition

交換排序 氣泡排序 和 快速排序

通過對比大小交換對比的元素所得到的排序為交換排序。冒牌排序時很常見的 通過對比相鄰元素的大小如果前面的元素比後面的大,則交換兩個元素,使得大的元素往後移。一 氣泡排序 二 快速排序,本文重點 快速排序在一次排序中有兩個方向,乙個是從尾部向前 逆向 乙個是從首部標誌 不包括首部標誌 向後 正向 正向和...

交換排序 氣泡排序和快速排序

1.氣泡排序 1 演算法思想 將序列中的第乙個元素和第二個元素相比較,如前者大於後者,則交換,否則不交換 再將第二個元素和第三個元素比較,若前者大於後者,則交換兩個元素的位置,否則不交換,依次進行,直到最後乙個元素,經過如此一輪,則n個元素中最大的乙個被放在了最後。此後,再進行相同的過程。2 基本實...

交換排序 氣泡排序和快速排序

這裡的測試資料來自於之前自己隨便寫的生成器 include using namespace std intmain int t 10,arr 20 while t return0 氣泡排序 void bubblesort int arr,int n if flag 0 return 氣泡排序 空間複...