Algorithms Lesson 1: Bubblesort
代碼
複雜度分析
n 個元素, 比較次數有 (n-1) + (n-2) + ...... + 1 = n(n-1)/2,
O(n2)
Algorithms Lesson 2: Insertion Sort
代碼
換個形式
算法複雜度
Algorithms Lesson 3: Merge Sort
代碼
Algorithms Lesson 4:Selection sort
代碼
複雜度分析
選擇排序的交換操作介於0和(n − 1)次之間。選擇排序的比較操作爲n(n − 1) / 2次之間。選擇排序的賦值操作介於0和3(n − 1)次之間。
比較次數O(n^2),比較次數與關鍵字的初始狀態無關,總的比較次數N=(n-1)+(n-2)+...+1=n*(n-1)/2。 交換次數O(n),最好情況是,已經有序,交換0次;最壞情況是,逆序,交換n-1次。 交換次數比冒泡排序少多了,由於交換所需CPU時間比比較所需的CPU時間多,n值較小時,選擇排序比冒泡排序快。
Algorithms Lesson 5:Merge sort
算法描述
代碼
算法複雜度
比較操作的次數介於(nlogn) / 2和nlogn − n + 1。 賦值操作的次數是(2nlogn)。 歸併算法的空間複雜度爲:Θ (n)
Algorithms Lesson 6:Quick sort
算法分析
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲兩個子序列(sub-lists)。
步驟爲:
- 從數列中挑出一個元素,稱爲 "基準"(pivot),
- 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,該基準是它的最後位置。這個稱爲分割(partition)操作。
- 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個算法總會結束,因爲在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。
代碼
Algorithms Lesson 7:Heapsort
算法分析
堆積樹節點的訪問
代碼
通常堆積樹(heap)是通過一維數組來實現的。在起始陣列爲 0 的情形中:
- 堆積樹的根節點(即堆積樹的最大值)存放在陣列位置 1 的地方;
注意:不使用位置 0,否則左子樹永遠爲 0[2]
- 節點i的左子節點在位置 (2*i);
- 節點i的右子節點在位置 (2*i+1);
- 節點i的父節點在位置 floor(i/2);
堆積樹的操作
在堆積樹的數據結構中,堆積樹中的最大值總是位於根節點。堆積樹中定義以下幾種操作:
- 最大堆積調整(Max_Heapify):將堆積樹的末端子結點作調整,使得子結點永遠小於父結點
- 建立最大堆積(Build_Max_Heap):將堆積樹所有數據重新排序
- 堆積排序(HeapSort):移除位在第一個數據的根結點,並做最大堆積調整的遞歸運算
歸併操作的工作原理如下:
- 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列
- 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置
- 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
- 重複步驟3直到某一指針達到序列尾
- 將另一序列剩下的所有元素直接複製到合併序列尾
如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數減去(n-1)次。平均來說插入排序算法複雜度爲O(n2)。因而,插入排序不適合對於數據量比較大的排序應用。但是,如果需要排序的數據量很小,例如,量級小於千,那麼插入排序還是一個不錯的選擇。