排序演算法 快排,歸併

2021-08-20 16:13:03 字數 2018 閱讀 3583

從陣列中隨機選乙個數,比這個數大的放右邊,比這個數小的放左邊。

快排中的乙個細節:如果乙個數等於p的時候,既可以在左邊又可以在右邊。這麼做是為了避免如果陣列中所有的數都一樣,則會造成資料的不平衡。快排的目的是能夠使得左邊和右邊的數都差不多,這樣的話時間複雜度就不會退化到o(n^2),而是o(n * logn)。

這裡是用遞迴實現的。但是這裡並不需要回頭。那麼為什麼需要遞迴呢?原因是迴圈的時候需要乙個引數,這個引數你一開始是不確定的,需要做完這一層之後才能確定接下來迴圈的引數。但是你又不能等每次迴圈結束之後再自己去新增引數。所以只能用遞迴來解決。

還有乙個細節是,每次left 和 right進行比較的時候以,要用 <= 而不是 < 。但是當做a[left]/a[right]和 pivot比較的時候,應該用< 而不是 <=。因為單純用 < 會造成死迴圈。在最左端只剩下兩個數的時候,會造成乙個死迴圈。有交集就會出現問題。只要是左右比較的時候,用 <= 而不用 <;當與中心點做比較的時候,用 < 而不用 <= 。

**如下所示:

public void quicksort(int a, int left, int right)

int mid = (left + right) /2

int target = a[mid];

while (left <= right)

while (left <= right && a[right] > target)

if (left <= right)

}quicksort(int a, 0, mid);

quicksort(int a, mid + 1, a.length - 1);

}

先區域性有序,再全域性有序。但是由於需要合併兩個陣列,所以需要額外空間。由於開闢空間和**空間需要時間消耗,所以歸併排序在實際應用上沒有快排好。

merge sort 採用分治的方法,但也是遞迴。 用雙指標方法比較兩個排序好的陣列。**的重點在於merge的過程。需要注意的點是當迴圈結束之後,left 或者 right中有乙個可能是沒有全部放進去的,這時候要再分別迴圈一次以保證所有數都放進去了。**如下:

public void sort(int a) 

public void mergesort(int a, int start, int end, int result)

int mid = (start + end) / 2;

mergesort(a, start, mid, result);

mergesort(a, mid + 1, end, result);

merge(a, start, end, result);

}public void merge(int a, int start, int end, int result)

else

while(leftindex <= mid)

while(rightindex <= end)

for(int i = 0; i <= end; i++)

}

時間複雜度的比較:

quick sort的平均時間複雜度是o(n * logn) 。最壞情況是o(n^2) ,這種最壞情況是:這個陣列已經是排好序的,而且每次選擇的時候都是選最小的(從小到大排)或者是最大的(從大到小排)。

merge sort 不管怎麼說,都是o(n * logn)。

quick sort 空間複雜度是o(1)

merge sort 額外空間是o(n)

只有merge sort是穩定排序,quick sort 是不穩定排序。(穩定性:重複的數會保證他們之間的相對順序)

這兩種演算法都是分治法。差別在於:quick sort 是先整體有序,再區域性有序。 merge sort是:先區域性有序,再整體有序。

快速選擇法:quick select。實際上就是快排中間的乙個部分。

kth largest element:利用快速排序的原理,時間複雜度是o(n)。這裡指的是平均時間複雜度。

heap sort: 

排序演算法 歸併 快排

歸併排序的思想是分治法,如果想要將乙個陣列排序,那麼將這個陣列分為左區間和右區間,左區間一定是小於右區間的,再將左區間繼續劃分,右區間也繼續劃分。最後將排好序的陣列全都歸併起來,這樣聽起來像是從上向下劃分,其實歸併排序主要是是從下向上,合併的過程。先將單個元素的陣列歸併為兩個元素的有序陣列 再將包含...

演算法整理 排序(歸併和快排)

趁找工作之際,著手對演算法進行相關學習和整理,便於自己複習鞏固,也以此來督促自己進行演算法的研究學習。通過對演算法的整理,一方面希望對於自己有所提高,另一方面,也希望提高自己的書面表達能力,文中有所不正確的地方,望批評指出,多謝。對於演算法學習,從簡單到複雜。今天主要整理一下排序相關的演算法。對於排...

排序演算法 冒泡 插入 歸併 快排

整理了一下幾種常見的排序演算法,包括冒泡 插入 歸併 快排。還有另外幾種待整理 堆排序 希爾排序 桶排序 直接上 include include include using namespace std void swap int a,int b 最簡單的氣泡排序,時間複雜度o n n void bu...