這是我第一次寫文章,想要記錄自己的學習生活,寫得不好請包涵or指導,本來想一口氣寫好多種,后來發現,寫太多的話反而可讀性不強,而且,我文筆,知識有限吶。慢慢來吧
目錄
名稱 | 冒泡排序 | 直接選擇排序 | 直接插入排序 | 希爾排序 |
---|---|---|---|---|
時間復雜度 | O(n^2) | O(n^2) | O(n^2) | O(n^(1.3-2) |
ps.沒有講到穩定性和空間復雜度。
冒泡排序
冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法。
它重復地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序(如從大到小、首字母從從Z到A)錯誤就把他們交換過來。走訪元素的工作是重復地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。
- 時間復雜度大約為O(n^2),可進行一些優化
這應該是c語言課程里頭第一次講到的排序算法,可以說得上是所有排序算法里頭最簡單的算法了。 - 思想:按一定的順序,比如要求從大到小進行排序,那么第一位到最后一位(也可從最后一位到第一位)依次進行多次比較
- 這個算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“冒泡排序”。
代碼實現(未優化版本)
1//這里按從小到大排序
2for(int i=0;i<n;i++)//比較n輪
3for(int j=0;j<n,j++)//n輪中每一輪比較n次
4{
5 if(a[j]>a[j+1])
6 {
7 temp=a[j];
8 a[j]=a[j+1];
9 a[j+1]=temp;
10 }
11}
代碼實現(優化版本)
1for(int i=0;i<n;i++)//比較n輪
2for(int j=0;j<n-i;j++)//每一輪比較n-j次
3{
4 if(a[j]>a[j+1])
5 {
6 temp=a[j];
7 a[j]=a[j+1];
8 a[j+1]=temp;
9 }
10}
為什么可以這樣優化呢?這就需要從機理來研究了,由於冒泡是每一次選出的是每一輪中的最大(小)的數,那么下輪開始,我們就不需要再將未排序的數再與已經排序的數進行比較了!
這里希望大家重視一下優化的版本,優化過后,時間復雜度會低些,這樣程序運行時間就會減少,雖然在冒泡這里體現並不明顯,但隨着學習的深入,你會逐漸發現,算法的優劣(時間復雜度&&空間復雜度),對一個程序而言很重要,特別是在信息學競賽中(才不會用冒泡這種低端算法呢)
02.直接選擇排序
直接選擇排序(Straight Select Sorting)
也是一種簡單的排序方法,它的基本思想是:第一次從R[0]R[n-1]中選取最小值,與R[0]交換,第二次從R[1]~R[n-1]中選取最小值,與R[1]交換,….,第i次從R[i-1]~R[n-1]中選取最小值,與R[i-1]交換,…..,第n-1次從R[n-2]R[n-1]中選取最小值,與R[n-2]交換,總共通過n-1次,得到一個按排序碼從小到大排列的有序序列。
-
ps.其實並不一定是從小到大,也可從大到小。 選擇排序的時間復雜度也是O(n^2)
-
思想:也是和冒泡一樣,進行多輪比較,但不一樣的地方在於,經過每一次比較之后,每一輪會確定一個最小(大)的數對應的位置,最后才進行一次交換,相比之下,冒泡是一直在交換,事實上,冒泡和直接選擇排序一樣,比較低端,能不用盡量不用,尤其對長度較大的數組。
代碼實現
1content_copy
2int temp;
3for(int i=0;i<n-1;i++)
4{
5 int k=i;
6 for(int j=i+1;j<n;j++)
7 if(a[j]<a[k])
8 k=j;//每一輪中選出最小的數組元素對應的下標
9temp=a[k];
10a[k]=a[i];
11a[i]=temp;
12}
動態圖解

03.直接插入排序
直接插入排序(Straight Insertion
Sort)是一種最簡單的排序方法,其基本操作是將一條記錄插入到已排好的有序表中,從而得到一個新的、記錄數量增1的有序表。
- 直接插入排序的時間復雜度還是O(n^2)
- 思想:每次選擇一個元素,將這個元素與數組中該元素之前所有的元素進行比較,然后將它插到合適的位置。
代碼實現
1 int i,j,temp;
2 for ( i = 1; i < n; i++) {
3 temp = a[i];//每一輪選出一個元素
4 for ( j = i; j > 0 && a[j - 1] > temp; j--) {
5 a[j] = a[j - 1];//與前面的元素比較大小,然后插進去,后面的元素退一位
6 }
7 a[j] = temp;
8 }
動態圖解

04.希爾排序
希爾排序(Shell's Sort)是插入排序的一種又稱“縮小增量排序”(Diminishing Increment
Sort),是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因D.L.Shell於1959年提出而得名。
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。希爾排序是基於插入排序的以下兩點性質而提出改進方法的: 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率。
但插入排序一般來說是低效的,因為插入排序每次只能將數據移動一位。
-
在某些極端情況下,希爾排序的時間復雜度會達到O(n^2)
-
希爾排序的平均時間復雜度是O(n^(1.3—2))
思想:直接插入排序要進行多次的比較交換,如果說,一個數組中大部分元素都處於有序的狀態下,那么就不需要進行多次的比較和交換了。那么就需要先對數組進行一定的處理。 -
以下是希爾增量下的希爾排序,關於希爾排序的增量,有很多種選擇,例如Hibbard增量,這些增量有些是通過數學證明得到的,有些則是還沒有得到證明的,人們確信正確的經驗得出的。。個人感覺有點像孿生素數猜想那樣的吧,但證明難度應該沒有那么高。
代碼實現
1 for (int gap= n/2; gap > 0; gap /= 2)//分組
2 {
3 for (int i = gap; i < n; i ++ )
4 {
5 int temp = a[i];
6 int j; //這里基本上和插入排序差不多
7 for (j = i; j >= gap && a[j - gap] > temp; j -= gap)
8 a[j] = a[j - gap];
9 a[j] = temp;
10 }
11 }
圖解
- ps.希爾排序的動圖我在網上找不到,只能用圖片代替了
對於這樣的一個數組,進行分組,gap=n/2,然后每分好之后,再gap/=2,一直到gap=1,這個過程使得數組的整體有序性提高,從而使直接插入排序的工作量減少很多.在這里插入圖片描述
對於其它增量實現的,這里不貼出來了,因為,我不會寫唉(逃
最后,這是我第一次寫博客,很多東西,如markdown語法什么的都不太會,我本來在編輯器上寫好的了,然后復制過來亂碼了,只能一段一段復制粘貼,希望大家包涵,如有錯誤,請指正,萬分感謝! 圖片來源於網絡,侵刪!