快排和堆排

2021-09-19 03:19:07 字數 3537 閱讀 4876

一、快速排序

最常用的排序演算法,速度通常也是最快的。

時間複雜度:o(nlogn)

最壞:o(n^2)

空間複雜度:o(nlgn)

不穩定(比如 5 3 3 4 3 8 9 10 11 這個序列,在中樞元素5和3交換就會把元素3的穩定性打亂)

實現原理:

快排主要是通過選擇乙個關鍵值作為基準值。比基準值小的都在左邊序列(一般是無序的),比基準值大的都

在右邊(一般是無序的)。依此遞迴,達到總體待排序序列都有序。

(1) 一次迴圈:從後往前比較,用基準值和最後乙個值比較,如果比基準值小的交換位置,如果沒有繼續比較下

乙個,直到找到第乙個比基準值小的值才交換。

(2) 找到這個值之後,又從前往後開始比較,如果有比基準值大的,交換位置,如果沒有繼續比較下乙個,直到

找到第乙個比基準值大的值才交換。

(3)直到從前往後比較陣列下標大於從後往前比較的陣列下標值,結束第一次迴圈,此時,對於基準值來說,左

右兩邊就是有序的了。

(4)接著分別比較左右兩邊的序列,重複上述的迴圈。

快速排序演算法分析:

(1)快速排序的時間效能取決於快速排序遞迴的深度,可以用遞迴數來描述演算法的執**況。

(2)如果遞迴數是平衡的,那麼此時的效能也是最好的。在最優的情況下,快

排序演算法的時間複雜度為o(nlogn)。

(3)就空間複雜度來說,主要是遞迴造成的堆空間的使用,最好情況,遞迴樹的深度 log2n ,其空間複雜度也就為 o(logn) ,最壞情況,需要進行遞迴呼叫,其空間複雜度為 o(n),平均情況空間複雜度也為 (logn)。

(4)關鍵字的比較和交換是跳躍進行的,因此,快速排序是種不穩定的排序方法。

二、堆排序

時間複雜度:o(n*logn)

特別適用於資料量很大的場合(百萬級資料)。因為快排和歸併排序都是基於遞迴的,資料量很大的

情況下容易發生堆疊溢位。

排序速度略低於快排。

也是一種不穩定的排序演算法。比如 3 27 27 36,如果堆頂3先輸出,則第三層(最後乙個27)跑到堆頂,

然後堆穩定,繼續輸出堆頂,是剛才那個27, 這樣說明後面的27先於第二個位置的27輸出,不穩定。

簡單介紹:

堆排序是指利用堆這種資料結構進行設計的一種排序演算法。堆排序利用了大根堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特徵,使得在當前無序區中選取最大(或最小)關鍵字的記錄變得簡單。

①堆是一棵順序儲存的完全二叉樹。完全二叉樹中所有非終端節點的值均不大於(或不小於)其左、右孩子節點的值。

②其中每個節點的值小於等於其左、右孩子的值,這樣的堆稱為小根堆;

③其中每個節點的值大於等於其左、右孩子的值,這樣的堆稱為大根堆;

實現原理:

將陣列構造成初始堆(若想公升序則建立大根堆,若想降序,則建立小根堆)從最後乙個節點開始調整,得到初始堆。

先構造出來大根堆(假設從小到大排序),然後取出堆頂元素(也就是最大的元素),放到陣列的最後面,然後再將剩餘的元素構造大根堆,再取出堆頂元素放到陣列倒數第二個位置,依次類推,直到所有的元素都放到陣列中,排序就完成了

如下圖所示:

三、二者之間的效率比較:

1、在陣列長度小於一千萬的時候,如下圖,快速排序的速度要略微快於歸併排序,可能是因為歸併需要額外的陣列開銷(比如宣告臨時local陣列用來儲存排序結果),這些操作讓歸併演算法在小規模資料的並不佔優勢

2.但是,當資料量達到億級時,歸併的速度開始超過快速排序了,如下圖,因為歸併排序比快排要穩定,所以在資料量大的時候,快排容易達到o(n^2)的時間複雜度,當然這裡是指未改進的快排演算法。

三、具體**實現

package com.tulun.src1.work;

public class sort ;

//呼叫堆排序陣列

//heapsort(arr);

quicksort(arr);

//輸出排序後的陣列

for(int i=0;i=0;i--)

for(int i=n;i>0;i--)

}//構造大頂堆函式,parent為父節點,length為陣列最後乙個元素的下標

public static void heapadjust(int arr,int parent,int length)

//如果父節點小於孩子節點,那就把孩子節點放到父節點上

arr[parent] = arr[i];

//把孩子節點的下標賦值給parent

//讓其繼續迴圈以保證大根堆構造正確

parent = i;

}//將剛剛的父節點中的資料賦值給新位置

arr[parent] = temp;

}//定義swap函式

//功能:將根元素(堆頂)與最後位置的元素交換

//注意這裡的最後是相對最後,是在變化的

public static void swap(int arr,int i)

/*** 快排

* @param arr

* @param low

* @param high

* @return

*/private static int partition(int arr,int low,int high)

if(low==high)

else

while(low < high && arr[low] <= temp)

if(low==high)

else

}arr[low]=temp;

return low;

}private static void quick(int arr,int low,int high)

if(part+1 < high)

}public static void quicksort(int arr)

}

快排 歸併 堆排

快排 include include include includeusing namespace std void quicksort vector a,int l,int r 終止遞迴的條件,子串行長度為1 int mid low high low 2 取得序列中間的元素 mergesort a...

快排與堆排

本文複習一下快速排序和堆排序 2 種排序演算法 為了多快好省地刷 leetcode 主要思想 通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。時間複...

Python 實現快排 堆排

原理 公升序 選取陣列的首個元素做為中間值,快取這個中間值,該位置變為空 從右到左和中間值對比,找到第乙個小於中間值的元素,把該值放到左邊的空位,該位置變為空 從左到右和中間值對比,找到第乙個大於中間值的元素,把該值放到右邊的空位,該位置變為空 重複步驟2和3,直到左右空位相交,然後把快取的中間值填...