1、冒泡排序:
时间复杂度 | 空间复杂度 | 稳定性 | 类型 | 备注 | |
冒泡排序 | 稳定 | 交换排序 | 每次都从0至i中交换出最大(小)的,沉下去。 | ||
选择排序 | 不稳定 | 选择排序 | 每次从剩下的i至n中,选择最大(小)的,并记录位置,再交换。 | ||
插入排序 | 稳定 | 插入排序 | 前i-1个排好序,选择第i个,从i-1往前寻找i插入的位置,顺序往右移动元素。 | ||
希尔排序 | 不稳定 | 插入排序 | 改进的插入排序,递减增量排序, | ||
快速排序 | 不稳定 | 交换排序 | 选择一个基准,从右边找比基准小的,同时从左边找比基准大的,然后将其交换,最后将基准移至分界点,左右递归使用快排。 特点:快速,数据移动少。 应用:寻找第k小(大)的数 | ||
归并排序 | 稳定 | 分而治之,分割从1开始,将有序数列按顺序合并,增加分割。 | |||
堆排序 | 不稳定 | 选择排序 | 构造堆,选择最大值,放到堆尾。说不清。 |
【备注】稳定性:相同元素在原未排序数列中的相对位置保持不变,则是稳定的。只有相邻的交换一般是稳定的,跳来跳去的不稳定。
插入排序代码:
void insertion_sort(int arr[], int len){
int i,j,temp;
for (i=1;i<len;i++){
temp = arr[i];
for (j=i;j>0 && arr[j-1]>temp;j--)
arr[j] = arr[j-1];
arr[j] = temp;
}
}
希尔排序(递减增量排序):
void shell_sort(int arr[], int len) {
int gap, i, j;
int temp;
for (gap = len >> 1; gap > 0; gap = gap >> 1)
for (i = gap; i < len; i++) {
temp = arr[i];
for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
arr[j + gap] = arr[j];
arr[j + gap] = temp;
}
}
归并排序
void merge_sort(int arr[],int len){
int *a=arr,*temp;
int *b=(int*)malloc(len*sizeof(int));
int seg;
for(seg=1;seg<len;seg=seg<<1){
int start,k=0;
for(start=0;start<len;start=start+(seg<<1)){//+运算法优先级高于<<, 切记加括号。不熟悉就用加法
int low=start;
int mid= start+seg < len ? start+seg :len;
int high = start+(seg<<1) < len ? start+(seg<<1) : len;
int start1=low,end1=mid;
int start2=mid,end2=high;
while(start1<end1 && start2 <end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while(start1 < end1)
b[k++] = a[start1++];
while(start2 < end2)
b[k++] = a[start2++];
}
temp = b;
b=a;
a=temp;
}
if(a != arr){
int k=0;
for(;k<len;k++){
b[k] = a[k];
}
b=a;
}
free(b);
}
快速排序:
void quick_sort(char *s, int left, int right){
if(left > right) return ; //需要退出条件
int i=left, j=right;
char ch_temp,mid=s[left];
while(i<j){
for(;s[j]>=mid && i<j;j--);//两个for顺序很重要,从右边找起,最后一个s[j]值会比mid小,所以可以和s[left]交换。
for(;s[i]<=mid && i<j;i++);
if(i<j){
ch_temp = s[i];
s[i] = s[j];
s[j] = ch_temp;
}
}
s[left] = s[i];
s[i] = mid;
quick_sort(s,left,i-1);
quick_sort(s,i+1,right);
}
堆排序:类似于选择排序,选择的方法不一样
void preHeap(int arr[],int len,int n){
int child,temp;
for(temp=arr[n];2*n+1<len;n=child){
child = 2*n+1;//求节点n的左子节点
if(child!=len-1 && arr[child] < arr[child+1]){
child++;
}
if(arr[child] > temp)
arr[n]=arr[child];
else
break;
}
arr[n] = temp;
}
void HeapSort(int arr[],int len){
int n;
for(n=len/2;n>=0;n--){
preHeap(arr,len,n);
}
int temp,i;
for(i=1;i<len;i++){
temp=arr[len-i];
arr[len-i]=arr[0];
arr[0]=temp;
Print(arr,len);
printf("\n");
preHeap(arr,len-i,0);
}
}
int main()
{
int arr[10]={2,87,39,49,34,62,53,6,44,98};
Print(arr,10);
printf("\n");
HeapSort(arr,10);
Print(arr,10);
printf("\n");
return 0;
}
可以复制一下程序,然后调试输出,自己弄懂原理。最好自己能够按照自己的理解写一遍。
参考:
https://www.runoob.com/cprogramming/c-sort-algorithm.html
https://www.cnblogs.com/0zcl/p/6737944.html
https://blog.csdn.net/m0_37962600/article/details/81475585#commentBox