2020-11-01

数据结构与算法之排序算法(三)

一、桶排序

算法思想:
核心就是将要排序的数据划分到m个有序桶中,然后对每一个桶内的数据进行排序。桶内排序之后,再依次取出每个桶内的数据,组成的数据就是有序的。
注意:
1、要排序的数据很容易划分为m个桶
2、数据在每个桶之间分布要是比较均匀的
3、桶排序比较适合外部排序
在这里插入图片描述

java代码:
public static void BucketSort(int[] a, int bucketSize){
	if(a.length < 2) return ;
	int maxValue = 0, minValue = 0;
	for(int i = 0 ; i < a.length ; i++){
		if(a[i] < minValue)
			minValue = a[i];
		else if(a[i] > maxValue)
			maxValue = a[i];
	}
	
	int BucketCount = (maxValue - minValue )/BucketSize +1;
	int[][] Bucket = new int[BucketCount][BucketSize];
	int[] IndexArr = new int[BucketCount];
	
	for(int i= 0 ; i < a.lenght ;i++){
		int bucketIndex = (a[i] - minValue) / bucketSize;
		if(IndexArr[bucketIndex] == Bucket[bucketIndex].length)
			ensureCapacity(Bucket,bucketIndex);
		Bucket[bucketIndex][IndexArr[bucketIndex]++] = a[i];
	}
	
	int k=0;
	for(int i =0 ; i < BucketSize;i++){
		if(Bucket[i].length <= 1)
			continue;
		QuickSort(Bucket[i], 0, IndexArr[i]-1);
		for(j = 0; j < IndexArr[i]; j++)
			a[k++] = Bucket[i][j];
	}
}

public static void QuickSort(int[] a, int l, int r){
	if(l < r){
		int pivot = Partition(a, l, r);
		QuickSort(a, l, pivot);
		QuickSort(a, pivot+1, r);
	}
}

public static void ensureCapacity(int[][] Bucket, int index){
	int[] temp = Bucket[index];
	int[] newbucket = new int[temp.length*2];
	for(int i = 0 ; i < temp.length ; i++){
		newbucket[i] = temp[i];
	}
	Bucket[index]= newbucket;
}

public static int Partition(int[] a, int l, int r){
	int point = a[r];
	int i = j = l;
	for(; j < r; j++){
		if(a[j] <= pivot){
			if(i == j)
				i++;
			else{
				int temp = a[i];
				a[i++] = a[j];
				a[j] = temp;
			}
		}
	}
	int m = a[r];
	a[r] = a[i];
	a[i] = m;
	return i;
}

二、计数排序

**算法思想:**其实是桶排序的一种特殊情况,当排序的n个数据所处的范围不发,(例如最大值为k,此时设为K个桶)每个桶内的数据都是相同的,再将这个数组求和,然后就可以知道每个数据的排列顺序了。
话不多说,上图。(no picture,you say eggs)
在这里插入图片描述

java代码

public static void countingSort(int[] a, int n){
	if(n <= 1) return;
	
	int max = 0;
	for(int i = 0 ; i < a.length ; i++){
		if(max < a[i])
			max = a[i];
	}
	
	int[] c = new int[max+1];
	for(int i = 0 ; i < a.length; i++)
		c[a[i]]++;
		
	for(int i = 1 ; i < c.length; i++)
		c[i]+=c[i-1];
		
	int[] r = new int[a.length];
	
	for(int j = n-1 ; j > 0; j--){
		int temp = c[a[i]]-1;
		r[temp] = a[i];
		c[a[i]]--;
	}

	for(int i = 0 ; i < a.length ; i++)
		a[i] = r[i];
}

三、基数排序

**算法思想:**比较一组比较大的数据,可以将其按位拆分,(例如比较手机号码a和b,如果前面几位中a已经比b大,后面的就不用比较)可以借助稳定排序算法,先按照最后一位排顺序,然后再倒数第二位重排。
在这里插入图片描述

public static void RadixSort(int[] a){
	int max = 0;
	for(int i = 0 ; i < a.length ; i++){
		if(max < a[i])
			max = a[i];
	}
	for(int exp = 0 ; max / exp > 0 ;exp*10)
		countingSort(a, exp);
}

public static void countingSort(int[] arr, int exp){
	if(arr.length <= 1)
		return;
	
	int[] c = new int[10];
	for(int i = 0; i < arr.length ; i++){
		c[(arr[i] / exp) % 10]++;
	}
	
	for(int i = 1 ; i < c.length ; i++)
		c[i]+=c[i-1];

	int[] r = new int[arr.length];
	for(int i = 0 ; i < arr.length ; i++){
		int index = c[(arr[i] / exp) % 10]-1;
		r[index] = a[i];
		c[(arr[i] / exp) % 10]--;
	}

	for(int i = 0 ; i < arr.length ; i++)
		arr[i] = r[i];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值