排序(三)

在这里插入图片描述

  • 归并排序
    今天写了最后一个排序算法,归并排序。
    归并是将两个或者两个以上的有序表组合成一个新的有序表。首先是两个两个元素进行归并,然后以两个元素排好序为一个单位,两个单位也就是四个元素进行归并,一次类推,这就是一个递归返回的过程。因此函数是递归调用的,首先将大表分为两部分,再将剩下的两部分再分为两部分,然后调用Merge函数,Merge函数的作用是将两部分的表合为一个有序表。
    空间复杂度是,辅助空间恰好占了n个单元,所以是O(n)
    时间复杂度:每一趟归并的时间复杂度是O(n),一共要进行O(log2n)次归并操作,因此时间复杂度是O(nlog2n)
    归并排序是一种稳定的排序
    代码
void merge(int num[],int low,int mid,int high)
{
	for(int k=low;k<=high;k++)
	{
		b[k]=num[k];
	}
	int i,j;
	int x=0;
	for(i=low,j=mid+1,x=low;i<=mid&&j<=high;x++)
	{
		if(b[i]<=b[j])
		{
			num[x]=b[i++];
		}
		else
		{
			num[x]=b[j++];
		}
	}
	while(i<=mid)
	{
		num[x++]=b[i++];
	}
	while(j<=high)
	{
		num[x++]=b[j++];
	}
	
}
void MergeSort(int num[],int low,int high)
{
	if(low<high)
	{
		int mid =(low+high)/2;
		MergeSort(num,low,mid);
		MergeSort(num,mid+1,high);
		merge(num,low,mid,high);
	}
	
}

与排序有关的面试问题

最佳的排序算法是:
每钟排序都有其优缺点,首先需要向面试官询问一些问题

  • 数据情况: 数据是已经排序还是基本已经排序,数据集有多大,可有重复的键值吗?
  • 排序的要求是什么:需要针对最坏情况和最好情况或者平均情况进行性能优化吗?排序算法需要稳定吗?
  • 系统的要求是什么:待排序数据是小于、等于还是大于可用内存?

排序例题:主目录服务器从多个部门目录服务器中接收已按用户ID排序的账户列表,那么能够在该主目录服务器中创建按用户ID排序的、综合全部账户的主列表的最佳方式是什么?

思路分析
数据特征:子列表已排序。将几个已排序的字列表进行排序,很像归并排序。在归并排序的最后阶段,在递归调用已经对子列表进行排序后,接下来就是合并列表,在归并排序中,合并操作时间复杂度为O(n),但是在这个例题中并不是两个归并,确定下一个需要合并的元素,需要扫描k个列表,扫描操作为O(k),需要为每一个排序的元素执行该操作,因此算法的复杂度为O(kn),如果K值较小,那没关系,如果k值较大,那就很影响总体时间。
因此应该着重优化如何从k个元素中找出最小或者最大的元素,这时候想到堆排序,大顶堆或者小顶堆中的堆顶就是最大或者最小的元素,并且每次调整堆的时间复杂度为O(log2n),如此找出最小元素的时间复杂度是O(log2k),每一个元素都要进行该操作,因此得到总体时间复杂度为O(nlog2k)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值