比较排序算法
比较排序算法包括:冒泡法、插入排序、归并排序、堆排序、快速排序和选择排序
比较排序算法基本上都是基于决策树模型,其排序算法下界均为O(NlogN)
冒泡排序
- 时间复杂度:O(N^2)
插入排序
- 时间复杂度:O(N^2)
- 应用于对于容量不大的数组
void InsertionSort(vector<int> &arr){
int len=arr.size();
int j=0;
int key=0;
for(int i=1;i<len;i++){
key=arr[i];
//insert arr[i] into the sorted sequence arr
j=i-1;
while(j>=0 && arr[j]>key){
arr[j+1]=arr[j];
j=j-1;
}
arr[j+1]=key;
}
}
归并排序
- 时间复杂度的上界为O(NlogN)
void Merge(vector<int> &arr, int p, int q, int r){
vector<int> L(arr.begin()+p,arr.begin()+q);
L.push_back(INT_MAX);
vector<int> R(arr.begin()+q+1,arr.begin()+r);
R.push_back(INT_MAX);
int i=j=0;
for(int k=p;k<=r;k++){
if(L1[i]<=R[j]) arr[k]=L[i++];
else arr[k]=R[j++];
}
}
void MergeSort(vector<int> &arr, int p, int r){
if(p<r){
int q=(p+r)/2;
MergeSort(arr, p, q);
MergeSort(arr, q+1,r);
Merge(arr, p, q, r);
}
}
堆排序
- 时间复杂度:O(NlogN)
- 过程:MaxHeapify, BuildMaxHeap, HeapSort
void MaxHeapify(vector<int> &arr,int length, int index){
int left=index*2+1;
int right=index*2+2;
int largest=index;
if(left<length && arr[left]>arr[largest]) largest=left;
if(right<length && arr[right]>arr[largest]) largest=right;
if(largest!=index) {
swap(arr[largest],arr[index]);
MaxHeapify(arr, length, largest)
};
}
void BuildMaxHeap(vector<int> &arr){
int len=arr.size();
for(int i=len/2;i>=1;i--)
MaxHeapify(arr, len, i-1);
}
void HeapSort(vector<int> &arr){
BuildMaxHeap(arr);
for(int i=arr.size()-1;i>=0;i--){
swap(arr[0],arr[i]);
MaxHeapify(arr, i, 0);
}
}
快速排序
- 时间复杂度:O(NlogN)
- 过程:partition, 两部分递归调用QuickSort
int partition(vector<int> &arr, int p, int r){
int x=arr[r];
int i=p-1;
for(int j=p;j<r;j++){
if(arr[j]<=x){
i=i+1;
swap(arr[i],arr[j]);
}
}
swap(arr[i+1],a[r]);
return i+1;
}
void QuickSort(vector<int> &arr, int p, int r){
if(p<r){
int q=partition(arr, 0, arr.size());
QuickSort(arr, p, q-1);
QuickSort(arr, q+1,r);
}
}
选择排序
- 时间复杂度:O(NlogN)
- 过程:
- 划分数组:(N+5)/5
- 计算每个划分数组的中位数(如果有偶数个就取下中位数)
- 最后将每组的中位数组成一个数组接着计算中位数,得到数值为x
- 按x划分原先的数组,如果有k个数被划分在x前面,则x就是第k+1小的数
- 如果想要找到的第i数的i比k小,就在k前面的数组重复上述步骤,如果比k大,就在k后面的数组重复上述步骤