常见排序算法思想

稳定的排序算法有:

1.冒泡排序:将小的数往前挪,将大的数往后挪。
2.插入排序:移动第i+1的那个数,在此数之前的序列中,从后往前进行比较相邻的两个数,将更小的数放前面,保证每次第i+1个之前的子序列有序。
3.归并排序:利用分治的思想,将一个无序的数组分解若干以两个数为一组的子数组,然后将每个子数组进行排序,可以得到若干连续的有序数组,再次合并排序合并直至最后为一个数组。

不稳定的排序算法有:

1.选择排序:每次都选择最小的数跟前面的数交换。
2.快排:也是利用分治的思想,以数组arr中的第i数为基准,将比arr[i]大的数放在一边,比arr[i]小的数放在一边。每个子数组一次类推即可完成快排。
3.希尔排序:取一个任意基准数(一般取集合长度的一半),然后将序列下标为该基数的倍数的数作为一个集合进行插入排序,通过缩小基数(新基数=基数/2),每改一次进行一次插入排序,直至基数为1为止即可完成希尔排序。
4.堆排:将数组建成一个大堆,然后将堆顶的数和堆低的数进行交换,然后堆的大小减1再次调整为大堆,再次交换以此类推,直至堆的大小为1。

各个排序算法时间/空间复杂度归纳

在这里插入图片描述

各个排序算法的使用场景:

对于数据量小的,基于他们的稳定性选择冒泡和插入排序。
对于数据相对有序的情况,我们也可以使用冒泡和插入或者快排,这时他们效率最高。
当数据量大的时候优先考虑归并,堆排,快排。
当数据完全属于无序的,使用快排最佳,但是堆排的空间复杂度最低,如果要求稳定性就要选择归并排序。
一般没有特殊的要求,快排还是比较常用的。

写一个简单的快排
int divarray(int arr[],int left,int right) {
	int key = arr[right];
	int k = left;
	for (int i = left; i < right; ++i) {
		if (arr[i]<key) {
			swap(arr[i],arr[k++]);
		}
	}
	swap(arr[right],arr[k]);
	return k;
}

void mysort(int arr[],int left,int right) {
	if (left< right) {
		int i = divarray(arr,left,right);
		mysort(arr,left,i-1);
		mysort(arr,i+1,right);
	}
}
TOP K问题以及大数据查找问题(高频)

这个问题是常问的问题,一定要答的精彩一点。
首先这个问题一定要追问面试官,具体的细节相关,如果是单纯的排序问题则是选择快排和堆排,堆排就可以使用优先级队列。
如果是具体的场景,比如要是找出微博热搜的前K个热搜话题,这时就可以问问面试官,内存是否够用?服务器有多少?单核还是多核?
如果对内存有要求且单一服务器,则应该先对文件进行哈希切分,切分为多个小文件,在再每个文件里面用哈希表统计次数,再进行排序,排完序取出前K个,再归并排序这些数据。
如果是分布式的服务器,则需要先在每个服务器上先用堆排或者快排求出前k个,求完之后再把这些前K个数据组合归并起来,之后再使用一次堆排。求出前K。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值