選擇類排序 (簡單選擇排序,堆排序)— c語言實現


選擇類排序包括:

  (1)  簡單選擇排序

(2)樹形選擇排序

(3)堆排序

簡單選擇排序:

【算法思想】:在第 i 趟簡單選擇排序中,從第 i 個記錄開始,通過 n - i 次關鍵字比較,從 n - i + 1 個記錄中選出關鍵字最小的記錄,並和第 i 個記錄進行交換

  時間復雜度:O(n^2)

 1 //此函數中a[0]不用,即對 a[1] ~ a[length-1] 排序;
//如果對a[0]~a[length-1]排序,將 for 循環中的 i = 1 改為 i = 0 即可,注意輸出
2 void select(int a[],int length){//length為數組的長度 3 int i,j; 4 int min;//記錄最小值的位置 5 6 for(i = 1;i < length - 1;i++){ 7 min = i; 8 //選擇最小的值 9 for(j = i + 1;j < length;j++){ 10 if(a[j] < a[min]) //更新最小值的坐標 11 min = j; 12 } 13 if(min != i){ 14 int temp; 15 temp = a[min]; 16 a[min] = a[i]; 17 a[i] = temp; 18 } 19 } 20 }

 堆排序:

堆排序是威洛母斯在1964年提出的對樹形選擇排序的改進算法,其只需要一個記錄大小的輔助空間,采用向量數組方式存儲,采用完全二叉樹的順序結構的特征進行分析,而非采用樹的存儲結構。

從小到大排序采用大根(頂)堆:r[i].key >= r[2i].key && r[i].key >= r[2i+1].key (結點值大於等於其左子與右子)

從大到小排序采用小根(頂)堆:r[i].key <= r[2i].key && r[i].key<= r[2i+1].key (結點值小於等於其左子與右子)

 

【算法思想】把待排序的記錄的關鍵字存放在數組 r[1...n] 中,將 r 看成一棵完全二叉樹的順序表示,每個結點表示一個記錄,第一個記錄 r[1] 作為二叉樹的根,以下各記錄 r[2] ~ r[n] 依次逐層從左到右順序排列,任意結點 r[i] 的左孩子是 r[2i] ,右孩子是 r[2i+1],雙親是 r[i/2]。對這棵二叉樹進行調整建堆。

時間復雜度:O(nlog2n)

  說明:在c語言中,i/2 的含義是整除,不同於數學中的定義,即 3/2 = 1,有一個向下取整的意思

堆排序可分為2步(從小到大排序):

<1> 建初堆:建立一個大根堆

<2>重建堆:進行 n - 1 趟的交換(r[1] 與 堆尾進行交換)和建堆的過程

 1 /*堆排序*/
 2 /*建初堆:大根堆*/
 3 void AdjustDown(int a[],int k,int len);  4 void BuildMaxHeap(int a[],int len){  5     int i;  6     for(i = len/2;i > 0;i--){  7  AdjustDown(a,i,len);  8  }  9 } 10 //調整堆 
11 void AdjustDown(int a[],int k,int len){ 12     a[0] = a[k];//將第一個記錄移出
13     int i; 14     for(i = 2*k;i <= len;i = 2*i){ 15         if(i < len && a[i] < a[i+1])//不能忘記i < len,否則會超出范圍 
16             i++;//取左右子中的最大值
17         if(a[0] >= a[i]) 18             break; 19         else{ 20             a[k] = a[i]; //將a[i]調整到其雙親結點上 
21             k = i; //修改k值,以便繼續向下篩選 
22  } 23  } 24     a[k] = a[0]; 25 } 26 
27 void HeapSort(int a[],int len){ 28  BuildMaxHeap(a,len); 29     int i; 30     int temp; 31     for(i = len;i > 1;i--){ 32         //第一個和堆尾進行交換
33         temp = a[1]; 34         a[1] = a[i]; 35         a[i] = temp; 36         //調整堆 
37         AdjustDown(a,1,i-1); 38  } 39 }

 圖可參照:https://blog.csdn.net/u013384984/article/details/79496052

測試:

 1 int main(){  2     int a[11] = {-1,2,3,1,4,7,3,5,1,6,0};  3     int b[11] = {-1,2,3,1,4,7,3,5,1,6,0};  4     int i,j;  5     select(a,11); //沒有用a[0],對后面的元素進行排序 
 6     HeapSort(b,10);//數組的最后一個下標,a[0]為輔助單元 
 7     for ( i = 1;i < 11;i++){  8         printf("%d \t",a[i]);  9  } 10     printf("\n"); 11     
12     for ( i = 1;i < 11;i++){ 13         printf("%d \t",b[i]); 14  } 15     printf("\n"); 16 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM