本文複習一下快速排序和堆排序 2 種排序演算法(為了多快好省地刷 leetcode )。
主要思想:
通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。時間複雜度 \(o(n \log n)\) ,空間複雜度取決於是否使用遞迴實現。
**實現:
int partition(vector&v, int p, int r)
swap(v[i + 1], v[r]);
return i + 1;
}void quicksort(vector&v, int p, int r)
}
對partition
函式的**(圖源為《演算法導論》):
在這裡的實現,我們缺省區間的最右側v[r] = 4
為主元,將上面所示的陣列分為 2 部分,左側小於等於 4,右側大於 4 。下面是函式中幾個臨時變數所表示的含義:
堆的性質:
子結點的鍵值總是小於(或者大於)它的父節點。三個步驟:
**實現:
class heap
inline int getright(int x)
void heapify(vector&v, int idx)
void buildheap(vector&v)
public:
void heapsort(vector&v)}};
heapify
函式**如下圖所示。需要注意的是,圖中陣列下標是從 1 開始的,而上面的**實現是從 0 開始的。
時間複雜度 \(o(\log n)\) .
在表示堆的陣列中,範圍 $\lfloor n/2 \rfloor $ 到 \(n-1\) 是葉子節點(下標從 0 開始),對於葉子節點,自然而然會滿足堆的性質,對葉子節點呼叫heapify
絲毫沒有影響,因此不需要調整。這就是為什麼for
迴圈的範圍是size/2 -> 0
。
時間複雜度為 \(o(n)\) .
呼叫buildheap
後的陣列,是乙個大頂堆,所以v[0]
是最大的數字,我們把它交換到陣列的最末尾處。然後對[0, heapsize)
範圍內的數字進行heapify
,因為影響的只有位置 0 ,所以只需要呼叫一次heapify(v, 0)
就能使得陣列滿足堆的性質。
時間複雜度 \(o(n\log n)\) .
heapsort
的**如下:
快排和堆排
一 快速排序 最常用的排序演算法,速度通常也是最快的。時間複雜度 o nlogn 最壞 o n 2 空間複雜度 o nlgn 不穩定 比如 5 3 3 4 3 8 9 10 11 這個序列,在中樞元素5和3交換就會把元素3的穩定性打亂 實現原理 快排主要是通過選擇乙個關鍵值作為基準值。比基準值小的都...
快排 歸併 堆排
快排 include include include includeusing namespace std void quicksort vector a,int l,int r 終止遞迴的條件,子串行長度為1 int mid low high low 2 取得序列中間的元素 mergesort a...
Python 實現快排 堆排
原理 公升序 選取陣列的首個元素做為中間值,快取這個中間值,該位置變為空 從右到左和中間值對比,找到第乙個小於中間值的元素,把該值放到左邊的空位,該位置變為空 從左到右和中間值對比,找到第乙個大於中間值的元素,把該值放到右邊的空位,該位置變為空 重複步驟2和3,直到左右空位相交,然後把快取的中間值填...