笔记4--桶排序及排序算法总结

基数排序

啥也不说了,看代码

int maxbits(int* arr,int n){		//计算arr数组中数的最大位数 
	int maxn = INT_MIN;
	for(int i = 0;i < n;++i){		//找到数组中最大的数 
		maxn = max(maxn,arr[i]);
	}
	int res = 0;
	while(maxn != 0){
		res++;
		maxn /= 10;
	}
	return res;
}

int getDigit(int x, int d) {		//从右往左取x的第d位数 
	return ((x / ((int) pow(10, d - 1))) % 10);
}

void radixprocess(int* arr,int begin,int end,int digit){
	const int radix = 10;
	int i = 0,j = 0;
	//有多少个数准备多少辅助空间 
	int bucket[end-begin+1];
	for(int d = 1;d <= digit;++d){		//有多少位就进出多少次 
		int count[radix] = {0};			//这个地方一定要给count数组赋初值 
		for(i = begin;i <= end;++i){
			j = getDigit(arr[i],d);		//d如果是1就取出个位数字,2就取出十位数字... 
			count[j]++;					//count数组表示0...9这几个位置一共有多少个数 
		}
		for(i = 1;i < radix;++i){	//将count数组装换 成前缀和数组 
			count[i] = count[i] + count[i-1];
		}
		for(i = end;i >= begin;--i){
			j = getDigit(arr[i],d);				// arr[i]的从右往左第d位数为j 
			bucket[count[j]-1] = arr[i];		//整个arr中从右往左第d位数小于等于j的一共是count[j]个,
			count[j]--;							// 所以arr[i]放在bucket的count[j]-1位置上 ,同时count[j]-- 
		}
		for(i = begin,j = 0;i <= end;++i,++j){	//将bucket中按从右往左第d的位数排好序的数放在arr中 
			arr[i] = bucket[j];					//准备下次轮按从右往左第d+1的位数进行排序 
		}
	}
}

void radixSort(int* arr,int n){
	if(n == 0 || n == 1) return;
	radixprocess(arr,0,n-1,maxbits(arr,n));
}

基于比较的排序算法
时间复杂度空间复杂度稳定性
选择排序O\left ( N^{2} \right )O\left ( 1 \right )
冒泡排序O\left ( N^{2} \right )O\left ( 1 \right )
插入排序O\left ( N^{2} \right )O\left ( 1 \right )
归并排序O\left ( N*logN \right )O\left ( N \right )
随机快排O\left ( N*logN \right )O\left ( logN \right )
堆排序O\left ( N*logN \right )O\left ( 1 \right )

 补充:

1.随机快排经过验证是是最快的

2.需要稳定性选择归并排序

3.对空间有要求选择堆排序

4.基于比较的排序:

        1)时间复杂度不能做到在O(N*logN)以下

        2)在时间复杂度最低且空间复杂度低于O(N)的情况下,不能做到稳定

 5.常见的坑:

        1)归并排序的额外空间复杂度可以变成O(1),但是非常难,不需要掌握,有兴趣可以搜“归并排序内部缓存法”

        2)“原地归并排序”的帖子都是垃圾,会让归并排序的时间复杂度变成O(N^2)

        3)快速排序可以做到稳定性问题,但是非常难,不需要掌握,可以搜“01stable sort”

        4)所有的改进都不重要,因为目前没有找到时间复杂度O(N*logN),额外空间复杂度O(1),又稳定的排序。

        5)有一道题目,是奇数放在数组左边,偶数放在数组右边,还要求原始的相对次序不变,碰到这个问题,可以怼面试官。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值