本文是為了加深自己對各種演算法的理解,部分摘自維基百科,這裡主要介紹較為常用的排序方法,一些生僻的演算法不做介紹。
.總結各種演算法之前,現介紹下幾個概念:
1、穩定度:穩定排序演算法會依照相等的關鍵(換言之就是值)維持紀錄的相對次序。也就是乙個排序演算法是穩定的,就是當有兩個有相等關鍵的紀錄r和s,且在原本的序列中r出現在s之前,在排序過的序列中r也將會是在s之前。
2、計算的複雜度(最差、平均、和最好表現),依據序列(list)的大小(n)。一般而言,好的表現是o(n log n),且壞的行為是o(n2)。對於乙個排序理想的表現是o(n)。僅使用乙個抽象關鍵比較運算的排序演算法總平均上總是至少需要o(n log n)。
.穩定排序:
* 泡沫排序(bubble sort) — o(n²)
* 插入排序 (insertion sort)— o(n²)
* 桶排序 (bucket sort)— o(n); 需要 o(k) 額外空間
* 計數排序 (counting sort) — o(n+k); 需要 o(n+k) 額外空間
* 合併排序 (merge sort)— o(n log n); 需要 o(n) 額外空間
* 二叉排序樹排序 (binary tree sort) — o(n log n)期望時間; o(n²)最壞時間; 需要 o(n) 額外空間
* 基數排序 (radix sort)— o(n·k); 需要 o(n) 額外空間
.不穩定排序
* 選擇排序 (selection sort)— o(n²)
* 希爾排序 (shell sort)— o(n log n) 如果使用最佳的現在版本
* 堆排序 (heapsort)— o(n log n)
* 快速排序 (quicksort)— o(n log n) 期望時間, o(n2) 最壞情況; 對於大的、亂數序列一般相信是最快的已知排序
.排序的演算法有很多,對空間的要求及其時間效率也不盡相同。下面列出了一些常見的排序演算法。這裡面插入排序和氣泡排序又被稱作簡單排序,他們對空間的要求不高,但是時間效率卻不穩定;而後面三種排序相對於簡單排序對空間的要求稍高一點,但時間效率卻能穩定在很高的水平。基數排序是針對關鍵字在乙個較小範圍內的排序演算法。
.這篇文章裡,將對幾種基礎排序介紹,包括氣泡排序、插入排序、選擇排序、快速排序。稍微複雜些的排序留在二中介紹。
.<<<<<<<<<<<<<<<<<<<<<<<
分割線》
.1、氣泡排序
氣泡排序是一種簡單的排序方法,演算法如下:
1. 首先將所有待排序的數字放入工作列表中。
2. 從列表的第乙個數字到倒數第二個數字,逐個檢查:若某一位上的數字大於他的下一位,則將它與它的下一位交換。
3. 重複2號步驟(倒數的數字加1。例如:第一次到倒數第二個數字,第二次到倒數第三個數字,依此類推...),直至再也不能交換。
用c語言實現如下:
intbubblesort(
int*a,
int b) }}
最差時間複雜度 o(n²)
最優時間複雜度 o(n)
平均時間複雜度 o(n²)
最差空間複雜度 o(n) total, o(1) auxiliary
.2、插入排序
插入排序也是一種簡單排序方法,演算法如下:
1. 從第乙個元素開始,認為該元素已經是排好序的。
2. 取下乙個元素,在已經排好序的元素序列中從後向前掃瞄。
3. 如果已經排好序的序列中元素大於新元素,則將該元素往右移動乙個位置。
4. 重複步驟3,直到已排好序的元素小於或等於新元素。
5. 在當前位置插入新元素。
6. 重複步驟2。
用c實現如下:
intinsertsort(
int*a,
int b)
} }}
最差時間複雜度 o(n²)
最優時間複雜度 o(n)
平均時間複雜度 o(n²)
最差空間複雜度 o(n) total, o(1) auxiliary
.3
、選擇排序
選擇排序的思想如下:
1. 設陣列內存放了n個待排數字,陣列下標從1開始,到n結束。
2. i=1
3. 從陣列的第i個元素開始到第n個元素,尋找最小的元素。(具體過程為:先設arr[i]為最小,逐一比較,若遇到比之小的則交換)
4. 將上一步找到的最小元素和第i位元素交換。
5. 如果i=n-1演算法結束,否則回到第3步
用c語言實現如下:
intselectsort(
int*a,
int b)
//選出從
i開始最小的元素
} temp = a[flag]
; a[flag]
= a[i]
; a[i]
= temp;
//交換元素 }}
最差時間複雜度 о(n²)
最優時間複雜度 о(n²)
平均時間複雜度 о(n²)
最差空間複雜度 о(n) total, o(1) auxiliary
.以上三種排序的時間複雜度都是o(n²)。
.4、快速排序
實踐證明,快速排序是所有排序演算法中最高效的一種。它採用了分治的思想:先保證列表的前半部分都小於後半部分,然後分別對前半部分和後半部分排序,這樣整個列表就有序了。
快速排序的基本演算法是:
1. 從數列中挑出乙個元素,稱為 "基準"(pivot),
2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,該基準是它的最後位置。這個稱為分割(partition)操作。
3. 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演算法總會結束,因為在每次的迭代(iteration)中,它至少會把乙個元素擺到它最後的位置去。
用c語言實現如下:
void
swap(
int*a,
int*b)
intquicksort(
int*a,
int b)
if(a[i]
else }}
快速排序的時間複雜度是o(nlogn),但是最壞情況下複雜度是o(n²)。
最差時間複雜度 θ(n²)
最優時間複雜度 θ(nlogn)
平均時間複雜度 θ(nlogn) comparisons
最差空間複雜度 根據實現的方式不同而不同
幾種常見排序演算法的介紹及複雜度分析
相關概念
1、穩定排序(
stable sort
)和非穩定排序
穩定排序是指所有相等的數經過某種排序演算法操作後仍然能保持它們在排序之前的相對次序。反之就是非穩定排序。 2
、內排序(
internal sorting
)和外排序(
external sorting)
在排序過程中,所有需要排序的數都在記憶體,並在記憶體中調整它們的儲存順序,稱為內排序;在排序過程中,只有部分數被調入記憶體,並借助記憶體調整數在外存中的存放順序排序方法稱為外排序。
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...
排序演算法總結
1 選擇排序 選擇排序的思想是依次從待排序數列中選擇最大 小 的 第二大 小 的等等,然後依次重新排列為有序數列。void selectionsort int a,int n if min i 時間複雜度o n 2 2 歸併排序 void merge int a,int left,int mid,i...
排序演算法總結
學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是 o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...