一、快速排序
最常用的排序演算法,速度通常也是最快的。
時間複雜度: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,直到左右空位相交,然後把快取的中間值填...