排序算法之归并和基数

排序算法根据是否需要访问外存,分为内部排序和外部排序。

内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。
外部排序是指大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,来达到排序整个文件的目的。
一.内部排序
使用内存,分为插入(直接插入排序  希尔排序)、选择(简单选择排序  堆排序)、交换(冒泡排序  快速排序)、归并、基数。


7.归并排序

分治思想

  • 基本思想:将两个有序的数组归并到另一个数组中,需要开辟额外的空间。
  • 代码实现(Java):
    public static void mergeSort(int[] arr) {
		if(arr==null || arr.length<2) {
			return ;
		}
		mergeSort(arr,0,arr.length-1);
	}
	
	public static void mergeSort(int[] arr,int left,int right) {
		if(left==right) {
			return ;
		}
		int mid=left+((right-left)>>1);
		mergeSort(arr,left,mid);
		mergeSort(arr,mid+1,right);
		merge(arr,left,mid,right);
	}
	
	public static void merge(int[] arr,int left,int mid,int right) {
		int[] temp=new int[right-left+1];
		int i=0;
		int p1=left;
		int p2=mid+1;
		while(p1<=mid && p2<=right) {
			temp[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
		}
		while(p1<=mid) {
			temp[i++]=arr[p1++];
		}
		while(p2<=right) {
			temp[i++]=arr[p2++];
		}
		for(i=0;i<temp.length;i++) {
			arr[left++]=temp[i];
		}
	}
  • 算法分析:时间复杂度为O(nlogn),是稳定排序。

8.基数排序 

基数排序基于桶排序,是分配排序的实现。分配排序的基本思想是排序过程无需比较关键值,通过分配和收集来实现排序。

桶排序的基本思想是:设置若干个桶,依次扫描待排序的元素,把关键字在某个范围内的元素全部装到第K个桶中(分配),然后按序号依次将各个非空的桶首尾连接起来(收集)。

桶的类型设计成链表,先进先出原则。桶排序的时间复杂度为O(m+n)。基数排序是对桶排序的一种改进。

  • 基本思想:对数字型或字符型的单关键字,可以看作由多个数位或字符构成的多关键字,此时可以采用“分配-收集”的方法进行排序,这一过程称为基数排序法,其中每个数字或字符可能的取值个数称为基数。即将待排数据中的每组关键字依次进行桶排序。
  • 代码实现(Java):
  • 算法分析:时间复杂度为O(n)(O(d * (n + r)),d 为位数,r 为基数,n 为原数组个数)。空间复杂度较高,且待排序的元素都要在一定的范围内。

9.总结

排序算法的复杂度和稳定性:

算法的稳定性是指排序前后,相等的两个元素次序不变。

                 

选择算法时要考虑的因素:待排序元素的数目、记录其他元素的内存大小、元素的结构及分布情况、对排序稳定性的要求。

设待排元素的大小为n,

  • 当n较大时,采用时间复杂度为O(nlogn)的算法:快速、堆、归并
  • 当n较大,内存空间无要求且要求稳定性时,选择归并排序
  • 当n较小时,可采用直接插入或直接选择排序:直接插入(元素分布有序)、直接选择(元素分布有序且不要求稳定性)
  • 一般不使用冒泡排序
  • 基数排序是稳定的,但存在一定的局限性:元素可分解,较适用于数字的排序且最好是无符号、数字较密集的序列。
  • 元素的移动次数与关键字的初始排列次序无关的是,基数排序
  • 元素的比较次数与初始序列无关的是,选择排序
  • 算法的时间复杂度与初始序列无关的是,选择排序、归并排序、堆排序
  • 不稳定的排序:快选希堆
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值