在上面一篇部落格當中,我們發現普通查詢和排序查詢的效能差別很大。作為乙個100萬的資料,如果使用普通的查詢方法,那麼每乙個資料查詢平均下來就要幾十萬次,那麼二分法的查詢呢,20多次就可以搞定。這中間的差別是非常明顯的。既然排序有這麼好的效果,那麼這篇部落格中,我們就對排序算做乙個總結。
按照我個人的理解,排序可以分為兩種:一種是非遞迴排序,它主要按照非遞迴的方法對資料進行排序,也就是說主要資料的移位和迴圈來完成;另外一種就是遞迴方法,我們在排列當前資料的時候首先把子資料排列有序,然後才會排列當前的資料。這種不斷遞迴呼叫的方法就是遞迴排序。
非遞迴排序的方法很多,這裡主要介紹氣泡排序、插入排序、希爾排序;遞迴的方法也不少,這裡介紹的方法是快速排序、歸併排序和堆排序。排序的內容很多,本篇部落格主要介紹非遞迴排序,遞迴排序的內容主要在下一節內容解決。
(1)氣泡排序
氣泡排序的內容並不複雜。假設有n個資料需要排序,那麼我們需要確定n個從大到小的資料,每一次都挑選第n大的資料是多少,並且放大相應的位置。直到所有的資料都排列整齊了,那麼我們的排序就結束了。
void bubble_sort(int array, intlength)}}
}
(2) 插入排序
插入排序的意思就是說,我們把資料分成兩個部分,一部分是已經排好序的資料,一部分是當前還沒有完成排序的資料。那麼這麼說來的話,排序的過程是不是就是把沒有排序的資料逐個插入到已經排好序的佇列中的過程呢。大家可以自己先試一下,然後再看看我的**對不對?
void insert_sort(int array, intlength)
else}}
}
那麼插入排序有沒有像氣泡排序那樣的改進方法呢?其實沒有。因為每一次插入排序的位置都是區域性比較的結果,而氣泡排序每一次的內容都是全域性最優的。這從資料比較的次數就可以看出來。
(3)希爾排序
希爾排序,我個人認為可以看成是氣泡排序的變種。它的基本思想是:
首先按照乙個序列遞減的方法逐漸進行排序。比如說有10個資料,我們按照序列5、3、1的順序進行排序。首先是5,那麼我們對1和6、2和7、3和8、4和9、5和10進行排列;
第二輪是3,那麼對資料1、4、7、10排列,再對2、5、8進行排列,以及3、6、9排列;
第三輪就和氣泡排序一樣了,以此對每個資料進行排列。它的優勢就是讓整個佇列基本有序,減少資料移動的次數,從而降低演算法的計算複雜度。
void shell_sort(int array, int length, intstep)
for(; outer >= (index + step); outer -=step)}}
}}
}
總結:
(1)上面的排序都是非遞迴程式,理解上不難,但是細節問題需要注意,特別是長度的問題
(2)**編寫的時候務必注意測試用例的設計
(3)如果可能的情況下,多使用已經驗證的**和函式
資料結構和演算法學習六,之非遞迴排序
在上面一篇部落格當中,我們發現普通查詢和排序查詢的效能差別很大。作為乙個100萬的資料,如果使用普通的查詢方法,那麼每乙個資料查詢平均下來就要幾十萬次,那麼二分法的查詢呢,20多次就可以搞定。這中間的差別是非常明顯的。既然排序有這麼好的效果,那麼這篇部落格中,我們就對排序算做乙個總結。按照我個人的理...
資料結構和演算法學習三,之遞迴和堆疊
引自 函式呼叫主要依靠ebp和esp的堆疊互動來實現的。那麼遞迴呢,最主要的特色就是函式自己呼叫自己。如果乙個函式呼叫的是自己本身,那麼這個函式就是遞迴函式。我們可以看一下普通函式的呼叫怎麼樣的。試想如果函式a呼叫了函式b,函式b又呼叫了函式c,那麼在堆疊中的資料是怎麼儲存的呢?函式a 函式b 位址...
資料結構和演算法學習三,之遞迴和堆疊
引自 函式呼叫主要依靠ebp和esp的堆疊互動來實現的。那麼遞迴呢,最主要的特色就是函式自己呼叫自己。如果乙個函式呼叫的是自己本身,那麼這個函式就是遞迴函式。我們可以看一下普通函式的呼叫怎麼樣的。試想如果函式a呼叫了函式b,函式b又呼叫了函式c,那麼在堆疊中的資料是怎麼儲存的呢?函式a 函式b 位址...