經常使用排序算法

 

1、交換排序算法

一、冒泡排序:冒泡排序是交換排序的一種,對於一個須要進行排序的數組來講,冒泡排序從頭開始對相鄰的兩個數之間進行比較,將較大(或較小)的數經過交換日後移動,也就是說第一次將最大(或最小)的那個數移動到最後,第二次將第二大(或第二小)的數移動到最後。數組

例如: 4 2 3 1 優化

第一次:2 3 1 43d

第二次:2 1 3 4blog

第三次:1 2 3 4排序

冒泡排序須要使用兩個for循環,假如數組a有n個數:遞歸

for(int i=0;i<n-1;i++)for循環

  for(int j=0;j<n-i-1;j++)二叉樹

    if(a[j]>a[j+1])循環

    {

      int temp=a[j];

      a[j]=a[j+1];

      a[j+1]=temp;

    }

時間複雜度:若是採用上述的代碼,使用了兩個for循環,時間複雜度計算爲(n-1)+(n-2)+(n-3)+……+1=n*(n-1)/2,即O(n*n)。最壞和平均時間複雜度都是O(n*n),最好的時間複雜度是O(n),這時候須要具有兩個條件,一個是數組自己已經排好序,同時算法進行了優化,若是數組自己已是排好序了,那麼無論怎麼循環,都不會出現交換的狀況,因此能夠在外層循環中的第一次循環的時候判斷是否有發生交換,若是沒有發生交換,那麼表示數組已經排好序了,這時候就退出再也不循環,那麼就只執行了n-1次代碼,時間複雜度是O(n)。

二、快速排序:快速排序是採用分治法,從數組中取出一個基準數,將比基準數小的放左邊,大的放右邊,再採用遞歸分別對兩邊進行一樣的操做。至於怎麼把小的放左邊,大的放右邊,時間複雜度是O(nlog2 n),最壞是O(n*n),基本思路是這樣的:

下標:   0     1      2     3

數值:   3     4      2     1

從後往前遍歷第一次: 

    0    1      2     3

    1  4   2     3

從前日後遍歷第一次:

    0    1     2     3

    1    3     2     4

從後往前遍歷第二次: 

    0    1      2     3

    1  2   3     4

 

(1)定義三個參數,第一個數的下標i,最後一個數的下標j,基準數s,i和j表示須要去遍歷的區間,在i下標以前的數都小於基準數,j下標以後的數都大於基準數,i和j在遍歷的過程是變化的,當i和j碰頭的時候,表示基準數左邊的都小於它,右邊的都大於它

(2)取第一個數做爲基準數,從 j 開始向 i 遍歷,找到第一個比基準數小的數,而後交換位置,更新 j 的值,這時候下標 j 後面的數都比基準數大

(3)接下來從 i 向 j 遍歷,找到第一個比基準數大的數,再交換位置,更新 i 的值,這時候 i 下標以前的數都比基準數小

(4)重複(2)(3)步的操做,對 i 到 j 的區間進行遍歷,直到 i 和 j 碰頭,這時候基準數左邊的數都比它小,後邊的都比它大

(5)對左右兩個區間執行一樣的操做,直到各區間只有一個數

2、插入排序

一、插入排序:插入排序將要排列的數組分紅已排序的部分和未排序的部分,將未排序部分的數拿出來,插入到已排序部分中的合適位置中,插入的時候,須要去移動排序部分的數。基本思路以下:

(1)將第一個數做爲已排序的部分,將後面的數做爲未排序的部分。取出第二個數,判斷和第一個的大小關係,若是第一個數比第二個數大,那麼將第一個數後移,而後將第二個數放在第一個的位置。這時候已排序部分就有兩個數了。

(2)接着取出第三個數,在已排序部分找到合適的插入位置,將已排序部分該位置以及以後的數都日後移動,而後將取出的數放入該位置。

(3)重複操做,直接將未排序部分的數全都插入到已排序部分。

 

時間複雜度:在最壞的狀況下,每次插入都要去遍歷全部的已排序部分,時間複雜度計算爲:1+2+3+……+n-1,和冒泡算法同樣,所以,最壞和平均時間複雜度是O(n*n)。當數組是倒序的,這時候每次從未排序部分取出一個數到已排序部分中去比較都只須要比較一次,總共插入n-1次,比較的次數是n-1,因此最好的時間複雜度是O(n)

 

二、希爾排序:插入排序的改進版,希爾排序實際上就是分組去執行插入排序,比方說:

(1)數組個數爲 n ,初始增量爲n/2,增量就是要分紅多少組,這裏分紅n/2組,對每一個組進行插入排序以後

(2)縮小增量爲(n/2)/2,而後繼續執行插入排序,直到只剩下一組。

最壞時間複雜度是O(n*n),跟插入排序同樣,最好是O(n),平均是O(n1.5),增量的大小定義會直接影響排序

 

3、選擇排序

一、選擇排序:選擇排序和插入排序相似,一樣將數組分紅已排序和未排序兩部分,每次從未排序中找到最大的或者最小的數去放在已排序部分的末尾。時間複雜度是O(n*n)。

二、堆排序:假如要構造一個從上往下升序的二叉樹

(1)先將數組寫成二叉樹的格式(建堆)

(2)從下往上,把最大的數往上交換到根節點,而後交換根節點和最深處的葉子節點的元素(構造大跟堆,交換堆頂元素和末尾元素)

(3)從下往上,把第二大的數往上升到根節點,再往下替換,以此類推(繼續調整堆結構,交換元素)。

時間複雜度爲:O(nlogn)

 

4、歸併排序

一、二路歸併排序:將一個待排序的數組分紅兩個組,分別對每一個組繼續分組,直到每組只剩下一個,這樣每一個組都是有序的,而後一直往上合併相鄰的組。思路是分組排序再合併。

相關文章
相關標籤/搜索