快速排序
- 平均时间复杂度O(nlogn),最坏时间复杂度O(n^2),时间开销与待排数组初始状态有关,当待排数组有序时,效率最低。
- 空间复杂度最坏O(n),最好O(logn)
int partition(int a[], int low, int high){
int pivot = a[low]; //表中第一个元素作为枢轴进行划分
int i = low, j = high;
while(i < j){
while(i < j && a[j] >= pivot)
--j;
a[i] = a[j]; //比枢轴小的元素移到左边
while(i < j && a[i] <= pivot)
++i;
a[j] = a[i]; //比枢轴大的元素移到右边
}
a[i] = pivot; //枢轴元素存放位置
return i; //返回划分的枢轴位置
}
void quickSort(int a[], int low, int high){
if(low < high){ //递归条件
int pos = partition(a, low, high); //划分左右子表
quickSort(a, low, pos-1); //左子表递归
quickSort(a, pos+1, high); //右子表递归
}
}
归并排序
- 时间复杂度为O(nlogn),与初始状态无关
- 空间复杂度O(n),需要辅助数组b
//a[low...mid],a[mid+1...high]为有序的两个子表,将其归并成a[low...high]有序的表
void merge(int a[], int low, int mid, int high){
int i, j, k;
int *b = (int *)malloc(sizeof(int) * (high-low+1)); //辅助数组
i = low, j = mid+1, k = 0;
while(i <= mid && j <= high){ //较小者加入a
if(a[i] <= a[j]){
b[k++] = a[i++];
}
else{
b[k++] = a[j++];
}
}
while(i <= mid){ //前表有剩余,直接加入归并表
b[k++] = a[i++];
}
while(j <= high){ //后表有剩余,直接加入归并表
b[k++] = a[j++];
}
//b中存放归并好的表,写回a中即可,注意a中数据位置要相对low偏移
for(i = 0; i < k; ++i){
a[i+low] = b[i];
}
}
void mergeSort(int a[], int low, int high){
if(low < high){
int mid = (low + high) / 2; //中间划分两个子表
mergeSort(a, low, mid); //左子表递归排序
mergeSort(a, mid + 1, high); //右子表递归排序
merge(a, low, mid, high); //归并左右子表
}
}
堆排序
- 时间复杂度O(nlogn),与初始状态无关
- 空间复杂度O(1)
//k为待调整子树的根节点
void heapAdjust(int a[], int k, int n){
int i;
a[0] = a[k]; //a[0]暂存子树根节点
for(i = 2*k; i <= n; i*=2){
if(i+1 <= n && a[i+1]>a[i]) //i指向左右孩子key较大者(右孩子存在的前提下)
i++;
if(a[0] >= a[i]) //根>=左右孩子,则调整完成
break;
else{
a[k] = a[i]; //左右孩子较大者上移到父节点位置
k = i; //根节点尝试"下坠",继续向下筛选
}
}
a[k] = a[0]; //根节点最终应该存放的位置k
}
//建立大根堆
void buildMaxHeap(int a[], int n){
int i;
for(i = n/2; i >= 1; --i){ //从第一个非叶子节点a[n/2]开始调整堆
heapAdjust(a, i, n);
}
}
//堆排序:①建堆;②堆顶堆底元素交换,调整堆
void heapSort(int a[], int n){
buildMaxHeap(a, n);
int i, temp;
for(i = n; i > 1; --i){ //n-1趟调整建堆过程
//堆顶元素和堆底元素交换,堆底为有序
//swap(a[i], a[1]);
temp = a[i];
a[i] = a[1];
a[1] = temp;
heapAdjust(a, 1, i-1); //调整,把剩余的i-1个元素整理成堆
}
}