(算法很美)排序小总结

本文总结了两种非比较排序算法——桶排序和基数排序,详细阐述了它们的工作原理、代码实现和时间复杂度。桶排序在数据均匀分布时效率高,基数排序适合整数排序,尤其在位数固定时。此外,还概述了十种常见排序算法,包括冒泡、选择、插入、希尔、快速、归并和堆排序等,探讨了它们的适用场景和时间复杂度。
摘要由CSDN通过智能技术生成

(算法很美)排序小总结

摘要:总结了桶排序和基数排序的相关知识和代码;归纳了十种重要的排序算法。
一、桶排序
1、通过 “分配”和 “收集”过程来实现排序;设计k个桶(编号0-k-1),然后n个输入数分布到各个桶中去,对各个桶中的数进行排序,然后按照次序把各个桶中的元素列出来即可。
2、实现需要链表(后面到链表时再写代码)
3、桶排序算法复杂度分析:
如果数据比较均匀则复杂度为O(N)
如果数据全部都分布到了一个桶里,那么用快排,时间复杂度为NlgN
设M为桶的数量,则时间复杂度为O(N+N(lgN-lgM)) (O(N+C)).
4、适用于数据较为均匀的情况

二、基数排序
1、从低位开始,根据其最低位进行排序,根据前面的顺序依次向高位进行排序。
2、时间复杂度为O(kn)
3、如果有负数的化先平移转换为正数,排序完再平移回来
4、通常用于十进制的排序处理

	//基数排序
	//10个桶,每个桶装的数个数不定
	//列表数组
	static ArrayList[] bucket=new ArrayList[10];
	public static void basicSort(int[] arr){
		//10个桶,每个桶装的数个数不定
		//列表数组
		//初始化桶
		for(int i=0;i<bucket.length;i++){
			bucket[i]=new ArrayList();
		}
		int d=1;//入桶依据的位初始化为1
		int max=arr[0];
	    //求出数组中的最大值
		for(int i=0;i<arr.length;i++){
			if(arr[i]>max)
				max=arr[i];
		}
		int maxd=1;
		//求出最大值的位数
		while(max/10!=0){
			maxd++;
			max/=10;
		}
		//从低位到高位进行排序
		while(d<=maxd){
			sort(arr,d++);
		}
	}
	public static void sort(int[] arr,int d){
		//全部入桶
		for(int i=0;i<arr.length;i++){
			//将元素arr[i]放到d对应的位置
			putInBucket(arr[i],getDigitOn(arr[i],d));
		}
		//每个桶中的元素再依次放回原数组
		int k=0;
		for(int j=0;j<bucket.length;j++){
			for(Object m:bucket[j]){//从列表中依次取出元素
				arr[k++]=(Integer)m;
			}
		}
		clearAll();//将桶清空
	}
	//将元素放入桶中
	public static void putInBucket(int a,int digition){
		switch(digition){
			case 0:
				bucket[0].add(a);
				break;
			case 1:
				bucket[1].add(a);
				break;
			case 2:
				bucket[2].add(a);
				break;
			case 3:
				bucket[3].add(a);
				break;
			case 4:
				bucket[4].add(a);
				break;
			case 5:
				bucket[5].add(a);
				break;
			case 6:
				bucket[6].add(a);
				break;
			case 7:
				bucket[7].add(a);
				break;
			case 8:
				bucket[8].add(a);
				break;
			case 9:
				bucket[9].add(a);
		}	
	}
	public static int getDigitOn(int a,int d){
		a=a/(int)Math.pow(10,d-1);
		return a%10;
	}
	//将桶清空的方法
	public static void clearAll(){
		for(ArrayList b:bucket){
			b.clear();//列表的清空方法
		}
	}

三、十种排序算法的总结
基础排序
a、冒泡排序:谁值大谁上,每一轮都把最大的顶到天花板上。效率太低O(n2)(要非常熟悉)

b、选择排序:效率较低O(n2),但经常用它内部的循环方式来找最大值和最小值

c、插入排序:虽然平均效率低,但在序列基本有序时,它很快,所以也有其使用范围。

d、希尔排序:(缩小增量排序)是对插入排序的改良,对空间思维训练有帮助。效率也比较低。

分治法
分治法三步:
(1)子问题拆分
(2)递归求解子问题
(3)合并子问题的解
e、快速排序:是软件工业中最常见的常规排序法,其双向指针扫描分区算法是核心,往往用于解决类似问题,特别是partition算法用来划分不同性质的元素。如果主元不是中位数,特别的如果每次主元都在数组区间一侧,复杂度将退化为N平方(最快找出第k小元素问题很重要)(重视子问题的拆分)
**工业上的优化:三点取中法,绝对中值法,小数据量用插入排序

f、归并排序:空间换时间–逆序对数(重视子问题的合并,开辟了辅助空间)

g、堆排序:用到了二叉堆数据结构,是继续掌握树结构的起手式。=插排+二分查找。(应用于海量数据)

** e、f、g都是NlgN的复杂度,其中快排表现最好,其原址不用开辟辅助空间;堆排也是原址,但是堆排时间复杂度的常数因素较大。
**上面的都是基于比较的排序,可证明它们在元素随机顺序情况下最好是NlgN的。

###下面三个是非比较排序,在特定情况下会比基于比较的排序快
1、计数排序,可以说是最快的:O(N+K),k=maxOf(sourceArr);
用它来解决问题时必须注意如果序列的值分布非常广(最大值很大,元素的分布很稀疏),空间就会浪费很多。
多以计数排序的适用范围是:序列的关键字比较集中,已知边界,且边界较小

2、桶排序:先分桶,再用其他排序方法对桶内元素排序,按桶的编号依次检出。
用它解决问题必须注意序列的值是否均匀地分布在桶中,如果不均匀,那么个别桶中的元素会远多于其他桶,桶内排序比较用比较排序,极端情况下,全部元素都挤在同一个桶里面,就会退化成NlgN.
其时间复杂度:O(N+C),其中C=N*(lgN-lgM),约等于N*lgN

3、基数排序,kN级别(k是最大数的位数)是整数数值向排序里面又快又稳的,无论元素分布情况怎么样,只开辟固定的辅助空间(10个桶)
对比桶排序,基数排序每次需要的桶的数量并不多。而且基数排序几乎不需要任何“比较操作”;而桶排序在桶的数量相对较少的情况下,桶内的多个数据必须进行基于比较操作的排序。
**因此在实际应用中,对十进制整数来说,基数排序更好用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值