排序算法对比
排序算法 | 类别 | 时间复杂度(平均) | 空间复杂度 | 稳定性 | 时间复杂度(最优) | 时间复杂度(最坏) |
---|---|---|---|---|---|---|
插入排序 | 插入排序 | O( n 2 n^2 n2) | O(1) | 稳定 | O(n) | O( n 2 n^2 n2) |
shell排序 | 插入排序 | O( n 2 n^2 n2) | O(1) | 不稳定 | O(n) | O( n 2 n^2 n2) |
选择排序 | 选择排序 | O( n 2 n^2 n2) | O(1) | 不稳定 | O( n 2 n^2 n2) | O( n 2 n^2 n2) |
堆排序 | 选择排序 | O( n l o g 2 n nlog_2n nlog2n) | O(1) | 不稳定 | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) |
冒泡排序 | 交换排序 | O( n 2 n^2 n2) | O(1) | 稳定 | O(n) | O( n 2 n^2 n2) |
快速排序 | 交换排序 | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | 不稳定 | O( n l o g 2 n nlog_2n nlog2n) | O( n 2 n^2 n2) |
归并排序 | O( n l o g 2 n nlog_2n nlog2n) | O(n) | 稳定 | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | |
基数排序 |
按照时间复杂度排序:
按照空间复杂度排序:
堆排序
时间复杂度:O(
n
l
o
g
2
n
nlog_2n
nlog2n)
空间复杂度:O(1)
稳定性:不稳定
类型:选择排序
算法原理:采用最大堆/最小堆来构造(完全二叉树),
其任何一非叶子节点满足 heap[i]<=heap[2i+1] && heap[i]<=key[2i+2]或者heap[i]>=heap[2i+1]&&heap[i]>=heap[2i+2]
算法实现:
- 构建堆:讲数组构造成最大堆
- 调整堆:从最后一个非叶子节点开始调整,将堆顶heap[1]与最后一个元素heap[n]交换,向上调整
C语言实现
void swap(int* a,int *b){
int tmp = *b;
*b = *a;
*a = tmp;
}
//初始化堆
void adjustHeap(int a[],int i,int n){
int child; //孩子结点
int temp; //临时变量
/*对堆进行整理*/
for(temp = a[i]; i * 2 + 1 < n; i = child){
child = i * 2 + 1; //当前结点的左孩子结点
if(child != n - 1 && a[child] < a[child + 1]) //比较左孩子和右孩子谁大
child++;
if(temp < a[child])
a[i] = a[child];
else
break;
}
a[i] = temp;
}
//堆排序
void myheapSort(int nums[],int n){
//初始化堆,构建最大堆
for(int i=n/2;i>=0;i--){ //从最后一个非终端节点开始,由下向上
adjustHeap(nums, i, n);
}
//进行堆排序
for (int i=n-1; i>=0; i--) {
swap(&nums[0], &nums[i]);
adjustHeap(nums, 0, i);
}
}