兩種排序均採用分治的思想:quick sort先整體有序,再局部有序。歸併排序先局部有序,再整體有序。
目錄:
- quick sort 和 merge sort 的比較
- quick sort
- merge sort
1. quick sort 和 merge sort 的區別於聯繫
1). 時間複雜度:都是O(nlogn),但是快速排序是平均O(nlogn),歸併排序是最好最壞都是O(nlogn)
quick sort的平均時間複雜度的計算:如有3個數字,則有6種排列情況,則期望的時間複雜度是:1/6 * (每種排列的時間之和)
2). 空間複雜度:快速排序耗費O(1)的額外空間,歸併排序不得不耗費O(n)的額外空間
3). 排序穩定性:快速排序是不穩定的排序算法。歸併排序是穩定的排序算法
4). 分治的思想:快速排序先整體有序再局部有序。歸併排序先局部有序再整體有序。
T(n) = 2 * T(n/2) + O(n)
2. quick sort -快速排序的原理和實現
1). 以某個元素爲基準,記錄其爲key,然後小於等於key的在左邊,大於等於key的在右邊。爲了使劃分更均勻。
2). 有以下幾個要點:綠色標出!
class Solution {
public:
/*
* @param A: an integer array
* @return:
*/
void sortIntegers(vector<int> &A) {
// write your code here
if(A.size()==0){
return;
}
quicksort(A, 0, A.size()-1);
}
void quicksort(vector<int> &A, int start, int end){
if(start >= end){
return;
}
int left = start, right = end;
//1.pivot,A[start],A[end]。取start或end做pivot,升序和降序是不好的情況,而選擇random更好,但是調用random的開銷大,折中之後用中點的數做pivot
//get value not index
int pivot = A[(start+end) / 2];
//2.left<=right not left < right
while(left<=right){
//3. A[left] < pivot not <=。此處是爲了較均勻的分爲左右兩部分
while(left<=right && A[left] < pivot){
left++;
}
while(left <= right && A[right] > pivot){
right--;
}
if(left <= right){
int tmp = A[left];
A[left] = A[right];
A[right] = tmp;
left++;
right--;
}
}
quicksort(A, start, right);
quicksort(A, left, end);
}
};
3. merge sort - 歸併排序的原理和實現
1).
class Solution {
public:
/*
* @param A: an integer array
* @return:
*/
void sortIntegers(vector<int> &A) {
// write your code here
if(A.size()==0){
return;
}
vector<int> temp(A.size(),0);
mergeSort(A, 0, A.size()-1, temp);
}
void mergeSort(vector<int> &A, int start, int end, vector<int> &temp){
if(start >= end){
return;
}
mergeSort(A, start, (start+end)/2, temp);
mergeSort(A, (start+end)/2+1, end, temp);
merge(A,start,end, temp);
}
void merge(vector<int> &A, int start, int end, vector<int> &temp){
int mid = (start+end)/2;
int lstart = start;
int rstart = mid + 1;
int index = lstart;
while(lstart<=mid && rstart<=end){
if(A[lstart] < A[rstart]){
temp[index++] = A[lstart++];
}
else{
temp[index++] = A[rstart++];
}
}
while(lstart <= mid){
temp[index++] = A[lstart++];
}
while(rstart<=end){
temp[index++] = A[rstart++];
}
for(int i = start;i<=end;++i){
A[i] = temp[i];
}
}
};