語言中,常用的算法有:冒泡排序、快速排序、插入排序、選擇排序、希爾排序、堆排序以及歸並排序等等。那麼從這篇開始,我將分別總結下這幾種排序法。
先交代一下,我們將要排序的數組定義為arr[N],即數組arr[]包含N個元素。
## 冒泡排序法(Bubblesort) ##
所謂排序法,就是對一組無序的序列進行有序的排序(從大到小或者從小到大),那麼什麼叫冒泡排序法,冒泡排序法又是怎麼實現數組的有序排列呢。
冒泡排序法的具體實現方法是這樣的,從數組的第一個元素`arr[0]`開始,兩兩比較**(`arr[n],arr[n+1]`),如果前面的數大於後面的數(`arr[n] > arr[n+1]`),那麼交換兩個元素的位置,把大的數往後移動。這樣依次經過一輪比較以後,最大的數將會被交換到最後的位置(arr[n-1])。
先一起再來看看冒泡排序法是怎麼排序的。
數組排序前 7 23 12 4 33 21 2 17 13 9
第一輪排序 7 12 4 23 21 2 17 13 9 33
第二輪排序 7 4 12 21 2 17 13 9 23
第三輪排序 4 7 12 2 17 13 9 21
第四輪排序 4 7 2 12 13 9 17
第五輪排序 4 2 7 12 9 13
第六輪排序 2 4 7 9 12
第七輪排序 2 4 7 9
第八輪排序 2 4 7
第九輪排序 2 4
可以看到,每一輪的排序,在這一輪中參與比較的元素中最大的數將會浮到最後。而冒泡排序的名字也是從這裡來的 。
C語言實現Bubblesort:
1 void bubblesort(int a[], int m) 2 { 3 int i,j; 4 int tmp; 5 int flag = 0; //設定標志,如果第一次循環比較時沒有發生交換,則說明數組是升序排序,不用排序,提前結束循環。 6 for(i = 0; i < m; i++) //外層循環控制循環次數 7 { 8 for(j = 0; j < m-1-i; j++) //內層循環控制每次循環裡比較的次數。 9 { 10 if(a[j] > a[j+1]) 11 { 12 tmp = a[j]; 13 a[j] = a[j+1]; 14 a[j+1] = tmp; 15 flag = 1; 16 } 17 } 18 19 if(0 == flag) 20 { 21 printf("No Sort\n"); 22 break; 23 } 24 } 25 }
## 選擇排序法(Selectionsort) ##
所謂的選擇是什麼意思呢,選擇就是於萬千花叢中擇其一,在選擇排序法中說的就是,每一次循環過程中,通過比較選擇出你需要的**最值**。
選擇排序法的過程是,通**過比較,選擇出每一輪中最值元素,然後把他和這一輪中最最前面的元素交換**,所以這個算法關鍵是要記錄每次比較的結果,即每次比較後最值位置(下標)。
先來看看選擇排序的過程:
數組排序前 7 23 12 4 33 21 2 17 13 9
第一輪循環 2 23 12 4 33 21 7 17 13 9
第二輪循環 4 12 23 33 21 7 17 13 9
第三輪循環 7 23 33 21 12 17 13 9
第四輪循環 9 33 21 12 17 13 23
第五輪循環 12 21 33 17 13 23
第六輪循環 13 33 17 21 23
第七輪循環 17 33 21 23
第八輪循環 21 33 22
第九輪循環 22 33
通過這個過程,我們可以看到,每輪循環過程中,都會找出這個最值元素,下一輪排序時就不用再考慮這個元素了。
C語言實現(Selectionsort)
1 void selectionsort(int a[],int m) 2 { 3 int i,j; 4 int k; 5 int tmp; 6 7 for(i = 0; i < m-1; i++)//控制循環次數,n個數需要n-1次循環 8 { 9 k = i; 10 for(j = i+1; j < m ; j++) 11 { 12 if(a[j] < a[k]) 13 k = j; 14 } 15 //i不等於k是就證明a[i]不是最小的, 16 //i等於k時證明a[i]就是本輪比較過程中最小的值 17 if(i != k) 18 { 19 tmp = a[i]; 20 a[i] = a[k]; 21 a[k] = tmp; 22 } 23 } 24 }
## 總結 ##
冒泡排序法是兩兩依次比較,並做交換,交換的次數多。
選擇排序法是每次循環找出最值,循環結束後將最值調整到合適位置,交換的次數少。