快排與堆排

2022-01-09 21:11:27 字數 1736 閱讀 4166

本文複習一下快速排序和堆排序 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,直到左右空位相交,然後把快取的中間值填...