常用排序演算法

2021-10-08 06:20:26 字數 3884 閱讀 9298

排序在演算法中起到很重要的作用,近來複習了很多排序演算法,打算在此做個小總結,順序依次是:插入排序、希爾排序、氣泡排序、 快速排序、選擇排序、堆排序、歸併排序。

排序在演算法中起到很重要的作用,近來複習了很多排序演算法,打算在此做個小總結,順序依次是:

插入排序

希爾排序

氣泡排序

快速排序

選擇排序

堆排序歸併排序

1. 暫存這個元素的值

2. 查詢要插入的位置,並將插入位置到插入元素原本位置的前乙個這一段距離的元素後移一位

3. 將暫存的元素值複製到插入位置

void

insertsort

(int a,

int n)

a[j]

=temp;

}}

這種方法也叫直接插入排序,因為查詢元素插入位置的時候,是從前往後逐個查詢的,效率較為低下。對於有序表,我們可以採取折半查詢的方法找到插入位置,然後再依次後移。

void

halfsort

(int a,

int n)

else

}for

(j=i-

1;j>=high+

1;j--

) a[j+1]

=a[j]

; a[high+1]

=temp;

}}

### 思想

將陣列劃分成h個小陣列,並對這些小陣列進行直接插入排序。

縮小增量h,比如h/2,對h/2個小陣列進行插入排序

直到增量h=1,即對整個陣列進行插入排序,但實際上此時只需要對陣列進行簡單地微調就可以了。

void

exch

(int a,

int i,

int j)

void

shellsort

(int a,

int n)

} h = h /3;

}}

將每個元素依次和後面的元素進行比較,若前面元素比後面大,則交換二者。直到每個元素都比較完。

void

bubblesort

(int a,

int n)}}

}

當我們遇到一種近乎有序的氣泡排序時,上面的演算法就進行了很多多餘的操作。所以我們對其進行優化,如果沒有發生交換,其實就已經說明表有序了,這時就可以退出冒泡了。

void

bubblesort

(int a,

int n)}if

(flag ==0)

return;}

}

1.選取乙個標定點,把比標定點大的元素放在標定點的右邊,小的放在左邊。

2.繼續對標定點左邊的一堆元素進行同樣的操作,同理右邊的元素也是一樣。

3.最後劃分的規模越來越小,就排序完成了。

//劃分

intpartition

(int a,

int low,

int high)

a[low]

=pivot;

return low;

}//快速排序

void

quicksort

(int a,

int low,

int high)

}

第i次遍歷表的時候,把第i個最小的元素放在第i個位置上。

void

selectionsort

(int a,

int n)

if(min_index!=i)

exch

(a,i,min_index);}

}

堆分為最大堆和最小堆,下面我們以最大堆為例。最大堆的根節點是最大的,其父節點總是大於結點自身,其子節點小於自身。由於這種性質,我們可以每次把最大堆的根節點放到陣列的末尾,然後向下調整堆,使其仍滿足最大堆的性質。

簡而言之,就是以下幾個步驟。

刪除根節點並記錄值

向下調整規模減1的堆

//向下調整

void

shiftdown

(int a,

int k,

int len)

if(a[k]

>a[j]

)break

;exch

(a,k,j)

; k=j;}}

//建立堆

void

buildheap

(int a,

int len)

}void

heapsort

(int a,

int len)

}

歸併排序的核心思想是把大規模的問題轉換成若干個小規模的問題。首先,用二分法把陣列拆成n/2個,n/4個,…,4個,2個,最後是由乙個元素組成的表,然後將其歸併為2個元素的有序表,繼續歸併成4個元素的有序表,最終歸併成n個元素的有序表。

void

merge

(int a,

int l,

int mid,

int r)

else

}while

(i<=mid) a[k++

]=b[i++];

while

(j<=r)a[k++

]=b[j++];

}void

mergesort

(int a,

int l,

int r)

}

排序名

空間複雜度

最好情況

最壞情況

平均情況

穩定性直接插入排序

o(1)

o(n)

o(n^2)

o(n^2)

穩定氣泡排序

o(1)

o(n)

o(n^2)

o(n^2)

穩定選擇排序

o(1)

o(n^2)

o(n^2)

o(n^2)

穩定希爾排序

o(1)

o(n^1.5)

o(n^1.5)

o(n^1.5)

不穩定快速排序

o(logn)

o(nlogn)

o(n^2)

o(nlogn)

不穩定歸併排序

o(n)

o(nlogn)

o(nlogn)

o(nlogn

穩定堆排序

o(1)

o(nlogn)

o(nlogn)

o(nlogn

不穩定桶排序

o(n+m)

o(n+m)

o(n+m)

o(n+m)

穩定基數排序

o(n+r)

o(d(n+r)

o(d(n+r)

o(d(n+r)

穩定直接插入排序在資料量小或者近乎有序的表中有很高的效能,因此經常和其他排序綜合運用。

氣泡排序在有序的情況下很好,但其他情況下不是很理想。

選擇排序無視序列表的初始狀態,就是不管是有序還是無序,對於選擇排序沒有影響,但選擇排序本身效能不是很好

希爾排序在增量為3的時候,效能比較好。

快速排序在有序或者逆序的情況下顯得特別蛋疼,但是他的綜合性能在內排序中最優。

歸併排序屬於外排序,因此在很大的資料量的情況下,使用歸併排序。但是歸併排序空間複雜度較高。

任何情況下,基於比較的排序演算法的時間複雜度的界限都是o(nlogn)

常用排序演算法

筆者最近學習演算法,學了很久也只弄懂了幾個排序演算法,在這裡曬一下下,作為以後參考之用。一 為什麼要研究排序問題 許多計算機科學家認為,排序演算法是演算法學習中最基本的問題,原因有以下幾點 l有時候應用程式本身需要對資訊進行排序,如為了準備客戶賬目,銀行需要對支票賬號進行排序 l很多演算法將排序作為...

常用排序演算法

一 簡單排序演算法 由於程式比較簡單,所以沒有加什麼注釋。所有的程式都給出了完整的執行 並在我的vc環境 下執行通過。因為沒有涉及mfc和windows的內容,所以在borland c 的平台上應該也不會有什麼 問題的。在 的後面給出了執行過程示意,希望對理解有幫助。1.冒泡法 這是最原始,也是眾所...

常用排序演算法

排序演算法 最好時間 平均時間 最壞時間 輔助空間 穩定性 直接插入排序 o n o n 2 o n 2 o 1 穩定 希爾排序 o n 1.3 o 1 不穩定 直接選擇排序 o n 2 o n 2 o n 2 o 1 不穩定 堆排序 o n x lbn o n x lbn o n x lbn o ...