两种排序均采用分治的思想: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];
}
}
};