排序演算法 選擇類排序

2021-07-25 19:40:36 字數 3506 閱讀 3197

選擇排序的演算法思想:

重待排序的元素序列中選擇最小(最大)的元素,將其放入在已排序序列的最前(最末),其餘的元素構成新的待排序列。依次類推,直到待排序元素序列中沒有待排元素。選擇排序主要有兩種:簡單選擇排序和堆排序。接下來我們來分別介紹一下這兩種排序演算法。

演算法思想:

簡單選擇排序是一種簡單的選擇類排序演算法,它是通過依次找到待排序列中最小的資料元素,並將其放在序列的最前面,從而使待排序元素變成有序序列。它的基本思想描述如下:

假設待排序的元素序列有n個元素,在第一趟排序過程中,從n個元素序列中選擇最小的元素,並將其放在元素序列的最前面即第乙個位置。第二趟排序過程中,從剩餘的n-1個元素中,選擇最小的元素,將其放在第二個位置。依次類推,直到沒有帶比較的元素,簡單選擇排序演算法結束。

例如,給定乙個待排序序列:55 33 22 66 44

過程如下:第乙個元素和其後的4個元素依次比較,55>33,33較小元素,33>22,22較小元素,22<66,22<44,較小元素任為22,最後將22與第乙個元素交換,第一趟排完:22 33 55 66 44。33分別與55、66、44比較,33最小不用交換,第二趟排完:22 33 55 66 44,依次類推,第三趟排完:22 33 44 66 55,第四趟排完:22 33 44 55 66,前4個元素全部有序,第5個元素是最大的元素,排在第五個位置上自然也是有序,排序結束。

示例:65 32 71 28 83 7 53 49

第一趟: 32 71 28 83 65 53 49

第二趟: 71 32 83 65 53 49

第三趟: 71 83 65 53 49

第四趟: 83 65 53 71

第五趟: 65 83 71

第六趟: 83 71

第七趟: 83

選擇排序演算法的實現:

void selectsort(int a,int n)

} }

主函式:

#include

void selectsort(int a,int n);/*簡單選擇排序*/

void disparray(int a,int n);/*輸出陣列序列*/

void heapsort(int a,int n);/*堆排序*/

int main();

int n=8;

selectsort(a,n);

//heapsort(a,n);

disparray(a,n);

return

0;}

輸出陣列函式:

void disparray(int a,int n)
主要用途:

簡單選擇排序演算法實現簡單,適用於待排序元素較少且對時間要求不高的場合。
穩定性與複雜度:

簡單選擇排序不是一種穩定的排序演算法。

在最好的情況下,待排序元素序列暗中非遞減排列,則不需要移動元素。在最壞的情況下,待排序按照非遞增排列,每一趟排序都需要移動元素,移動次數為3(n-1)。在任何情況下,簡單選擇排序演算法都需要n*(n-1)/2次比較,總上所述,簡單選擇排序演算法時間複雜度為o(n2)。空間複雜度為o(1)。

堆排序也是屬於選擇類排序,它是簡單選擇排序演算法的改進。堆排序利用二叉樹的性質對元素進行排序,將完全二叉樹從上到下、從左到右依次編號,如果每乙個雙親節點元素值大於(小)等於該孩子節點的元素值,則根據編號構成的元素序列就是乙個大(小)頂堆。
演算法思想:

假設乙個大頂堆中有n個元素,如果將堆中的根節點元素輸出之後,再將剩下n-1個元素重新建立成乙個新堆,並將根節點元素輸出,然後將剩下的n-2個元素重新建立成堆,重複上述過程,知道堆中沒有元素為止。輸出的元素就是乙個有序序列,這樣的排序方法稱為堆。
1、建立堆

假設待排序元素有n個 ,依次放在陣列a中,第1個元素的關鍵字a[1]表示二叉樹的根節點,剩下的元素a[2...n]依次與完全二叉樹中的編號一一對應。例如,a[1]的左孩子節點元素放在a[2]中,右孩子節點元素放在a[3]中,a[i]的左孩子放在a[2*i]中,右孩子放在a[2*i+1]中。

如果是大頂堆,則有a[i]>=a[2*i]且a[i]>=a[2*i+1] (i=1,2,...|n/2|向下取整)。

建立大頂堆的演算法思想:從位於元素序列中最後乙個非葉子結點(第|n/2|元素)開始,逐層比較調整元素的位置使其滿足a[i]>=a[2*i]且a[i]>=a[2*i+1] ,直至根節點為止。假設當前節點序號為i,則當前元素為a[i],其左孩子為a[2*i]右孩子a[2*i+1]。將左孩子為a[2*i]右孩子a[2*i+1]與a[i]比較,如果孩子節點元素值大於當前節點值,則交換兩者;否則不交換。逐層向上執行此操作,直至根節點,這樣就建立大頂堆。

i: 1 2 3 4 5 6 7 8

a[i]: 27 58 42 53 42 69 50 62

(1)初始狀態

(2)從第4個元素開始,53<62,交換兩個節點元素。

(3)比較第3個元素與其子樹節點,因為69>50且42<69,所以交換42和69。

(4)比較第2個元素與其子樹節點,因為62>42且62<58,所以交換58和62。

(5)比較第1個元素與其子樹節點,因為69>62且27<69,所以交換27和69。

(6)比較第3個元素與其子樹節點,因為50>42且27<50,所以交換27和50。

void createheap(int a,int n)
2、調整堆

調整堆演算法描述:輸出堆頂元素可以將堆頂元素放在堆的最後面,即將第1個元素與最後乙個元素交換,則需要調整的元素序列就是a[1...n-1]。從根節點開始,如果其左、右節點元素值大於根節點元素值,選擇較大的乙個進行交換,也就是說如果a[2]>a[3],則將a[1]與a[2]驚喜交換,否則不交換。如果a[3]>a[2],則將a[1]與a[3]驚喜交換,否則不交換。逐層重複執行此操作,直至葉子節點,就完成了堆的調整,構成了乙個新堆。
void adjustheap(int a,int s,int m)

a[s]=t;/*將根節點插入到正確的位置*/

}

堆排序:

void heapsort(int a,int n) 

}

主要用途:

堆排序演算法實現比較複雜,它主要適用於大規模的資料排序,例如,如果需要在10萬個資料元素找出前10個最小元素或最大元素,則適用堆排序演算法效率最高。
穩定性和複雜度:

堆排序是不穩定排序演算法。堆排序的時間耗費主要是在建立堆和調整堆時。乙個深度h,元素個數為n的堆,其調整演算法的比較次數最多是2(h-1)次,建立乙個堆最多比較次數4n。乙個完整的堆排序過程總共比較次數少於2nlog2n,依次堆排序平均時間複雜度和最壞時間複雜度都是o(nlog2n)。堆排序空間複雜度為o(1)。

排序演算法之選擇排序類

我們可以從圖上可以看出,我們先迴圈找出最小的元素。我們的第二個迴圈是找出最小的元素,第乙個迴圈是負責交換值的,第一趟排序外層迴圈的指標指向陣列的第乙個,這個時候我們找出陣列的最小值,和外層指標交換數值,就把最小的放在第乙個,後面的同理。注意 1 重點在於先迴圈找出最小的值,再去交換 function...

排序演算法 選擇排序

private static int leftchild int i private static void perc int a,int i,int n for int i 0 ir j break else public static void heasp int r,int n for i 0...

排序演算法 選擇排序

摘自 wiki百科 選擇排序 selection sort 是一種簡單直觀的排序演算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾 目前已被排序的序列 以此類推,直到所有元素均排序完畢。c語言實現 vo...