八種排序演算法總結之C 版本

2021-07-09 03:44:36 字數 4851 閱讀 7441

八種排序演算法總結之

c++版本

五種簡單排序演算法

一、            氣泡排序 【穩定的】

void bubblesort( int* a,int count )  //

實現從小到大的最終結果

現在注意,我們給出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)

二、            交換排序    【穩定的】

void exchangesort( int *a,int count)

時間複雜度為o(n*n)

三、            選擇法  【不穩定的】

void selectsort( int *a,int count)

a[pos] = a[i];

a[i] = temp;

}遺憾的是演算法需要的迴圈次數依然是1/2*(n-1)*n。所以演算法複雜度為o(n*n)。

我們來看他的交換。由於每次外層迴圈只產生一次交換(只有乙個最小值)。所以f(n)<=n

所以我們有f(n)=o(n)。所以,在資料較亂的時候,可以減少一定的交換次數。

四、            插入法  【穩定的】

void insertsort( int *a,int count)

a[pos+1] = temp;

}其複雜度仍為o(n*n)。

最終,我個人認為,在簡單排序演算法中,直接插入排序是最好的。

五、            希爾排序法   【不穩定的】

/**  

希爾排序,n為陣列的個數*/

void shellsort( int arr, int n ) 

arr[ pos + d] = temp;

}} while( d > 1 );}

三種高階排序演算法

一、        快速排序   輔助空間複雜度為o(1)  【不穩定的】

void quicksort( int *a,int left, int right)

} while ( i//

如果兩邊的下標交錯,就停止(完成一次)

//當左半邊有值(left),遞迴左半邊

if( left < j )

quicksort( a,left, j);

//當右半邊有值(right>i),遞迴右半邊

if( i < right )

quicksort( a, i,right);

它的工作看起來象乙個二叉樹。首先我們選擇乙個中間值middle,程式中我們使用陣列中間值,然後把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對後交換)。然後對兩邊分別使用這個過程(最容易的方法——遞迴)。注意,由於資料的隨機性,對middle的選擇並不會影響該演算法的效率。

注意,在掃瞄過程中,對於給定參考值,對於向右(左)掃瞄,如果掃瞄值大(小)於或等於參考值,就需要進行交換。最終得到的結果是,

j左邊的值都小於參考值,而

i右邊的值都大於參考值,j和

i之間的值都等於參考值。對j左邊和i右邊的分別使用遞迴,就可以完成最終的排序。

這裡我沒有給出行為的分析,因為這個很簡單,我們直接來分析演算法:首先我們考慮最理想的情況

1.陣列的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。

2.每次我們選擇的值剛好是中間值,這樣,陣列才可以被等分。

第一層遞迴,迴圈n次,第二層迴圈2*(n/2)......

所以共有n+2(n/2)+4(n/4)+...+n*(n/n)= n+n+n+...+n=k*n=log2(n)*n

所以演算法複雜度為o(log2(n)*n)

其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那麼他將變

成交換法(由於使用了遞迴,情況更糟),但是糟糕的情況只會持續乙個流程,到下乙個流程的時候就很可能已經避開了該中間的最大和最小值,因為陣列下標變化了,於是中間值不在是那個最大或者最小值。但是你認為這種情況發生的機率有多大??呵呵,你完全不必擔心這個問題。實踐證明,大多數的情況,快速排序總是最好的。

如果你擔心這個問題,你可以使用堆排序,這是一種穩定的o(log2(n)*n)演算法,但是通常情況下速度要慢

於快速排序(因為要重組堆)。

二、        歸併排序(兩種實現方法均要掌握)   【穩定的】

歸併排序是一種極好的外部排序方法,即針對資料儲存在磁碟上而不是高速記憶體中的問題。

//以下程式參考資料結構課本p286頁的模板,為使用指標鍊錶實現的

#include

using

namespace std;

struct node;

node * divide_from( node * head )

}second_half =  midpoint->next;

midpoint->next =null; //

在這裡將原鏈拆斷,分為兩段

return second_half;

}node * merge( node * first, node * second)

else

}if( first==null )

last_sorted->next= second;

else

last_sorted->next= first;

return combined.next; //

返回啞節點的後繼指標,即為合併後的鍊錶的頭指標 }

//這裡的引數必須是引用呼叫,需要這個指引去允許函式修改呼叫自變數

void mergesort( node * &head)

}int main()

cout//呼叫歸併排序後的結果

head = p1;

while( head != null )

cout<//以下程式為使用陣列實現的歸併排序,輔助空間複雜度為o(n)

#include

using

namespace std;

void merge( int data, int left, int mid, int right )

else

}if( i//

左邊的陣列尚未取盡

for( j=i; j < n1; j++,k++)

data[k] =l[j];

else

//if( j//

右邊的陣列尚未取盡  ,

這句話可要可不要

for( i=j; idata[k] =r[i];

delete l;   //

**記憶體

delete r;}/*

*   left:陣列的開始下標,一般為0;right:陣列的結束下標,一般為 (n-1)

*/void mergesort( int data, int left, int right )

}int main();//

排序前的輸出

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

cout<" ";

cout//排序後的輸出

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

cout<" ";

cout<

三、        堆排序     【不穩定的】

/*

*  

向堆中插入current元素的函式*/

void insert_heap( int data,const int ¤t, intlow, int high )

}data[ low ] =current;}/*

*  

建立堆函式,num為陣列data的元素個數

*  

只有乙個結點的<2-樹》自動滿足堆的屬性,因此不必擔心樹中的任何樹葉,即

*  

不必擔心表的後一半中的元素。如果從表的中間點開始並從後向前工作,就

*   

能夠使用函式insert_heap去將每個元素插入到包含了所有後面元素的部分堆

*  

中,從而建立完整的堆。 */

void build_heap( int data, int num ) }/*

*  

堆排序主函式,num為陣列data的元素個數*/

void heap_sort( int data, int num )

}int main()

;for(int i=0; i< sizeof(a)/sizeof(int); i++)

cout//呼叫堆排序

for(int i=0; i< sizeof(a)/sizeof(int); i++)

cout

八種排序演算法總結

插入排序 1.直接插入排序 原理 將陣列分為無序區和有序區兩個區,然後不斷將無序區的第乙個元素按大小順序插入到有序區中去,最終將所有無序區元素都移動到有序區完成排序。要點 設立哨兵,作為臨時儲存和判斷陣列邊界之用。實現 void insertsort node l,int length void s...

排序演算法之八 桶排序 C 版本

實現中,使用vector作為桶,只是從編碼便利的角度出發。因為需要對各個桶進行單獨排序,所以,對桶進行的排序演算法是否穩定,影響了整個演算法的穩定性,這裡使用的是sort演算法,因此整個演算法就是不穩定的。void bucketsort int pdata,int size 建立桶 int buck...

八種排序演算法

include include 氣泡排序 void boblesort int arr,int n 插入排序 void insertsort2 int arr,int n 希爾排序 void shellsort2 int arr,int n 選擇排序 void selectsort int arr,...