堆排序,计数排序...

堆排序

将数组堆化的思路
在这里插入图片描述
代码

package;

public class D2 {
	public static void main(String [] args) {
		int arr[]= {5,3,8,5,2,9,10,6,4,99};
		MINHeap(arr);
		sort(arr);
		for(int i=0;i<arr.length;i++)
		System.out.print(arr[i]+" ");
		
	}
	
private static void sort(int[] arr) {
		for(int i=arr.length-1;i>-1;i--) {
			int h=arr[0];
			arr[0]=arr[i];
			arr[i]=h;
			//这里满足这个函数的递归条件
			MinHeapFicDown(arr,0,i);//这里用i+1 不要把刚换完的又换上去了
			//后来发现这个和方法是要传个数。改回来了
		}
			
		
	}

static void MINHeap(int arr[]) {
	int n=arr.length/2;
	for(int i=n-1;i>-1;i--) {
		MinHeapFicDown(arr,i,n*2);
	}
}

private static void MinHeapFicDown(int[] arr, int i,int n) {
	int left=2*i+1;
	int right=2*i+2;
	if(left>=n)
	return;
	int min=left;
	if(right<n) {
	if(arr[right]<arr[left])
	min=right;}
/*
 * 交换 这里错误了 没有和根比较 int c=arr[min]; arr[min]=arr[i]; arr[i]=c;
 */
	if(arr[min]<arr[i])
		{int c=arr[min]; arr[min]=arr[i]; arr[i]=c;
	///条件:由于上层的数具体多大未知 而下层的数据已经是小堆
	//又回到了和原问题相同条件的子问题,递归调用,继续调整
	//这就是从倒数第二层的最后一个节点开始调整的好处
	MinHeapFicDown(arr,min,n);}
	else return;
}

}

这里码代码的时候,就是思路不够清晰明了,导致没有比较,还有传参数的时候的那个n是数组的个数,要搞清。还有弄清递归。

时间复杂度
在这里插入图片描述

计数排序

在这里插入图片描述
在这里插入图片描述
开辟辅助空间
在这里插入图片描述

桶排序

在桶中需要动态的存储空间,需要用到链表
在这里插入图片描述
时间复杂度
在这里插入图片描述

基数排序

第一步
以LSD为例,假设原来有一串数值如下所示:
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
第二步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
第三步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。
效率分析编辑
时间效率 [1] :设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。
实现方法编辑
最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。
最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。
实现原理编辑
基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

在这里插入图片描述
有负数的话需要转成正数,即全部数加最小值的绝对值加1.排完序再扣除,也是类似于通往排序,需要链表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值