幾種常見的排序算法

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次之間。選擇排序的賦值操作介於03(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) / 2nlognn + 1賦值操作的次數是(2nlogn)。 歸併算法的空間複雜度爲:Θ (n)

 

 

 

 

Algorithms Lesson 6:Quick sort

算法分析

快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲兩個子序列(sub-lists)。

步驟爲:

  1. 從數列中挑出一個元素,稱爲 "基準"(pivot),
  2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,該基準是它的最後位置。這個稱爲分割(partition)操作。
  3. 遞歸地(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):移除位在第一個數據的根結點,並做最大堆積調整的遞歸運算

歸併操作的工作原理如下:

  1. 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列
  2. 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置
  3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
  4. 重複步驟3直到某一指針達到序列尾
  5. 將另一序列剩下的所有元素直接複製到合併序列尾

如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數減去(n-1)次。平均來說插入排序算法複雜度爲O(n2)。因而,插入排序不適合對於數據量比較大的排序應用。但是,如果需要排序的數據量很小,例如,量級小於千,那麼插入排序還是一個不錯的選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章