各種常規排序演算法總結

2021-06-01 04:51:55 字數 4581 閱讀 6337

基本思想是:每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子表中的適當位置,直到全部記錄插入完成為止。常規插入排序分兩種,即直接插入排序和希爾排序。

假設待排序的記錄放在陣列r[0...n-1]中,排序過程的某一中間時刻,r被劃分成兩個子區間r[0..i-1]和r[i..n-1],其中:前乙個區間是已經排好序的有序區,後乙個子區間是當前未排序的部分,不妨稱為無序區。直接插入排序的基本操作是將當前無序區的第乙個記錄r[i]插入到r[0..i-1]中適當的位置,使r[0..i]變為新的有序區-------演算法時間複雜度o(n^2)。

// 插入排序

void insertsort(int array, int length)

// 在合適位置安放當前元素

array[j + 1] = key;

}}

希爾排序也是一種插入排序方法,實際上是一種分組插入方法。基本思想是:先取定乙個小於n的整數d1作為第乙個增量,把錶的全部記錄分成d1個組,所有距離為d1的倍數的記錄放在同乙個組中,在各組內進行直接插入排序;然後取第二個增量d2(

// shell排序

void shellsort(int array, int length)

// 在合適位置安放當前元素

array[j+increment] = key;

}}

基本思想:兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時,即進行交換,直到沒有反序的記錄為止。

基本思想是,通過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡一般逐漸往上「漂浮」直至「水面」。整個演算法是從最後面的記錄開始,對每兩個相鄰的關鍵字進行比較,且使關鍵字較小的記錄換至關鍵字較大的記錄之上,使得經過一趟氣泡排序後,關鍵字最小的記錄到大最上端,接著,再在剩下的記錄中找到關鍵字次小的記錄,並把它換在第二個位置上,依次類推,一直到所有記錄都有序為止。演算法時間複雜度o(n^2)。

//氣泡排序

void bubble_sort(int a, int length)

} if(tag == 1)

}}

快速排序是由氣泡排序改進而得的,它的基本思想是:在待排序的n個記錄中任取乙個記錄(通常取第乙個記錄),把該記錄放入適當位置後,資料序列被此記錄劃分成兩部分。所有關鍵字比該記錄關鍵字小的記錄放置在前一部分,所有比它大的記錄放置在後一部分,並把該記錄排在這兩部分的中間(稱為該記錄歸位),這個過程稱作一趟快速排序。之後對所有的兩部分分別重複上述過程,直至每個部分內只有乙個記錄或為空為止。簡單的說,每趟使表的第乙個元素放入適當位置,將表一分為二,對子表按遞迴方法繼續這種劃分,直至劃分的子表長為1或0.-------演算法最好時間複雜度o(nlog2n)

// 對乙個給定範圍的子串行選定乙個樞紐元素,執行完函式之後返回分割元素所在的位置,

// 在分割元素之前的元素都小於樞紐元素,在它後面的元素都大於這個元素

int partition(int array, int low, int high)

array[low] = pivot;

// 返回樞紐元素所在的位置

return low;

}// 快速排序

void quicksort(int array, int low, int high)

}

基本思想:每一趟從待排序的記錄中選出關鍵字最小的記錄,順序放在已排好序的子表的最後,直到全部記錄排序完畢。由於選擇排序方法每一趟總是從無序區中選出全域性最小(或最大)的關鍵字,所以適合於從大量的記錄中選擇一部分排序記錄,如,從10000個記錄中選擇出關鍵字前10位的記錄,就適合使用選擇排序法。

直接選擇排序法:第i趟排序開始時,當前有序區和無序區分別為r[0..i-1]和r[i..n-1](0≤ i≤n-1),該趟排序則是從當前無序區中選出關鍵字最小的記錄r[k],將它與無序區的第乙個記錄r[i]交換,使得r[0..i]和r[i+1..n-1]分別為新的有序區和新的無序區

//直接選擇排序

void selectsort(int array,int nlength)

if(k != i)

swap(&array[k],&array[i]);

}}

n個關鍵字序列kl,k2,…,kn稱為堆,當且僅當該序列滿足如下性質(簡稱為堆性質):

(1) ki≤k2i且ki≤k2i+1 或(2)ki≥k2i且ki≥k2i+1(1≤i≤)

若將此序列所儲存的向量r[1……n]看做是一棵完全二叉樹的儲存結構,則堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。

堆的這個性質使得可以迅速定位在乙個序列之中的最小(大)的元素。

堆排序演算法的過程如下:1)得到當前序列的最小(大)的元素 2)把這個元素和最後乙個元素進行交換,這樣當前的最小(大)的元素就放在了序列的最後,而原先的最後乙個元素放到了序列的最前面 3)交換可能會破壞堆序列的性質(注意此時的序列是除去已經放在最後面的元素),因此需要對序列進行調整,使之滿足於上面堆的性質。重複上面的過程,直到序列調整完畢為止。

// array是待調整的堆陣列,i是待調整的陣列元素的位置,length是陣列的長度

void heapadjust(int array, int i, int nlength)

// 最後把需要調整的元素值放到合適的位置

array[i] = ntemp;

}// 堆排序演算法

void heapsort(int array, int length)

}

歸併排序是多次將兩個或兩個以上的有序表合併成乙個有序表。最簡單的歸併是直接將兩個有序的子表合併成乙個有序的表。

兩個有序表直接合併成乙個有序表的演算法merge().設兩個有序表存放在同一陣列中相鄰的位置上:r[low..mid],r[mid+1..high],先將他們合併到乙個區域性的暫存陣列r1中,待合併完成後將r1複製到r中。每次從兩個段中取出乙個記錄進行關鍵字的比較,將較小者放入r1中,最後將各段中餘下的部分直接複製到r1中。

void merge(int array,int start,int mid,int end)

while(i <= mid)

p[k++] = array[i++];

while(j <= end)

p[k++] = array[j++];

k = 0;

while(start <= end)

array[start++] = p[k++];

free(p);

}//歸併排序

void mergesort(int array,int start,int end)

}

在之前介紹過的排序方法,都是屬於[比較性]的排序法,也就是每次排序時,都是比較整個關鍵字的大小以進行排序。計數排序是乙個非基於比較的線性時間排序演算法。

計數排序演算法的基本思想是對於給定的輸入序列中的每乙個元素x,確定該序列中值小於x的元素的個數。一旦有了這個資訊,就可以將x直接存放到最終的輸出序列的正確位置上。例如,如果輸入序列中只有17個元素的值小於x的值,則x可以直接存放在輸出序列的第18個位置上。

//計數排序

//nmaxvalue為陣列array中最大值

void countingsort(int array,int nmaxvalue,int nlength)

for(i = 1; i <= nlength; i++)

array[i-1] = presult[i];

}

基數排序的主要思路是,將所有待比較數值(注意,必須是正整數)統一為同樣的數字長度,數字較短的數前面補零. 然後, 從最低位開始, 依次進行一次穩定排序.這樣從最低位排序一直到最高位排序完成以後, 數列就變成乙個有序序列.

比如這樣乙個數列排序: 342 58 576 356, 以下描述演示了具體的排序過程

第一次排序(個位):

3 4 2

5 7 6

3 5 6

0 5 8

第二次排序(十位):

3 4 2

3 5 6

0 5 8

5 7 6

第三次排序(百位):

0 5 8

3 4 2

3 5 6

5 7 6

結果: 58 342 356 576

//基數排序

//nmaxbit為數字中的最高位數,如最大數為235,則nmaxbit為3

void radixsort(int *array, int nlength ,int nmaxbit)

// 此過程確定小於元素x的元素的個數

for(i = 1; i < 10; i++)

temp[i] += temp[i-1];

for(i = nlength-1; i >= 0; i--)

for(i = 0; i < nlength; i++)

array[i] = presult[i];

nradix *= 10;

}}

常規排序演算法總結

首先推薦乙個學習資料結構的優秀的視覺化 主要總結以下6種排序演算法,其中插入排序 選擇排序 歸併排序 快速排序。1.氣泡排序 bubble sort 和快速排序 quick sort 和隨機快速排序 random quick sort 博文待寫 2.插入排序 insertion sort 和希爾排序...

各種排序演算法總結

注 以下所講排序,以公升序排序為例!選擇排序 作者思路 在一組數中,選擇第乙個數標記為最小值,在剩下的數中找比它小的數,若找到則交換兩數,標記新的 最小值 然後繼續往下找,這樣一趟下來就可以找到一組數中第二小的值,第二次以第二個數作為最小值,如此迴圈下去。這是最簡單 最基礎的一種排序演算法。例子 1...

各種排序演算法總結

1 插入排序 void insertsort int a,int n a j 1 key 插入排序是穩定的排序,平均和最壞時間複雜度是o n 2 最好的時間複雜度是o n 對應於全部排好序的情況。2 氣泡排序 void bubblesort int a,intn 氣泡排序是穩定的排序,平均和最壞時間...