Given an integer array, sort it in ascending order. Use quick sort, merge sort, heap sort or any O(nlogn) algorithm.
Given [3, 2, 1, 4, 5]
, return [1, 2, 3, 4, 5]
.
快速排序是排序算法中比較重要一種,也是經常容易考的一種排序算法,務必要掌握好。快排的優點是其平均時間復雜度為O(nlgn),這樣在給大數據集排序的時候,其效率明顯比一些O(n2)的算法要高很多。快排主要有三步:
1. 選定中樞點pivot value,中樞點可以選擇中間那個點,也可以選末尾點,一般來說我們直接選取末尾點,如果選末尾點的話注意循環結束后要調換中樞點和第一個大於中樞點的數的位置。理論上來說中樞點可以為任意值,即使這個值不在數組上存在也無妨。
2. 分割Partition,重新安排數字的位置,讓所有比中樞點小的數到左半邊,所有大於中樞點的書到右半邊,等於中樞點的數可以在任意一邊,這樣數組就被分為了兩段,注意兩段的長度可以不相等。
3. 分別給每段排序,調用遞歸算法給每一段排序。
下面這個圖是用來說明步驟二,分割的過程,這是快排的核心,只要這一步搞清楚了,基本了快排就能掌握了。
(from http://www.algolist.net/Algorithms/Sorting/Quicksort)
解法一:
// Quick sort class Solution { public: /** * @param A an integer array * @return void */ void sortIntegers2(vector<int>& A) { quick_sort(A, 0, A.size() - 1); } void quick_sort(vector<int> &A, int start, int end) { if (start >= end) return; int pos = partition(A, start, end); quick_sort(A, start, pos - 1); quick_sort(A, pos, end); } int partition(vector<int>& A, int start, int end) { int i = start, j = end, pivot = A[end]; while (i <= j) { while (A[i] < pivot) ++i; while (A[j] > pivot) --j; if (i <= j) { swap(A[i], A[j]); ++i; --j; } } swap(A[i], A[end]); return i; } };
下面這種方法的快排跟上面的一點不同在於partition函數,上面使用的是while循環下面這種使用的是for循環,看個人愛好了,兩種都行:
解法二:
// Quick sort class Solution { public: /** * @param A an integer array * @return void */ void sortIntegers2(vector<int>& A) { quick_sort(A, 0, A.size() - 1); } void quick_sort(vector<int> &A, int start, int end) { if (start >= end) return; int pos = partition(A, start, end); quick_sort(A, start, pos - 1); quick_sort(A, pos, end); } int partition(vector<int>& A, int start, int end) { int i = start - 1, pivot = A[end]; for (int j = start; j < end; ++j) { if (A[j] <= pivot) { ++i; swap(A[i], A[j]); } } swap(A[i + 1], A[end]); return i + 1; } };
類似題目: