各种排序算法总结

1、冒泡排序:

 

 时间复杂度空间复杂度稳定性类型备注
冒泡排序O(n^2)O(1)稳定交换排序每次都从0至i中交换出最大(小)的,沉下去。
选择排序O(n^2)O(1)不稳定选择排序每次从剩下的i至n中,选择最大(小)的,并记录位置,再交换。
插入排序O(n^2)O(1)稳定插入排序前i-1个排好序,选择第i个,从i-1往前寻找i插入的位置,顺序往右移动元素。
希尔排序 O(1)不稳定插入排序改进的插入排序,递减增量排序,
快速排序O(nlogn)O(nlogn)不稳定交换排序

选择一个基准,从右边找比基准小的,同时从左边找比基准大的,然后将其交换,最后将基准移至分界点,左右递归使用快排。

特点:快速,数据移动少。

应用:寻找第k小(大)的数

归并排序O(nlogn)O(n)稳定 分而治之,分割从1开始,将有序数列按顺序合并,增加分割。
堆排序O(nlogn) 不稳定选择排序构造堆,选择最大值,放到堆尾。说不清。

【备注】稳定性:相同元素在原未排序数列中的相对位置保持不变,则是稳定的。只有相邻的交换一般是稳定的,跳来跳去的不稳定。

插入排序代码:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值