golang排序算法--基数排序

原理
基数排序的思想其实挺有意思,举个栗子来说,有如下数组:


第一趟:
我们首先对这个数组按照其个位数进行分组,结果如下:

然后将分组后的数据按照索引的大小取出,得到新的数组如下:

第一趟排序后完成的工作为将数组按照个位数由小到大的顺序进行了排序

第二趟:
对第一趟的结果按照十位数进行分组,结果如下:

然后将分组后的数组按照索引的大小分别取出,得到新的数组如下:

第二趟排序后完成的工作是将数组按照十位数由小到大进行了排序,同时由于个位数已经进行了排序,因此将分组后的数组按照索引大小取出时,十位数相同的较小的会排在前面,如31和38,43和49

第三趟:
对第二趟的结果按照百位数进行分组,结果如下:

然后将分组后的数组按照索引的大小分别取出,得到新的数组如下:

第三趟排序后完成的工作是将数组按照百位数由小到大进行了排序,同时由于个位数和十位数都已经进行了排序,所以较小的数会排在前面

这样就完成了整个数组的排序。

由上面的过程可以知道如果最大数有n位,则需要n次(按照索引分组+按照索引大小取出数据)
两个小前提:
1.下面写的算法是对全为正整数的数组进行排序
2.该算法必须要先知道这个数组中最大值得位数,如999是3位
 


// 基数排序
func BaseSort(data []int) []int {
	if len(data) < 2 {
		return data
	}
	max := data[0]
	dataLen := len(data)
	for i := 1; i < dataLen; i++ {
		if data[i] > max {
			max = data[i]
		}
	}
	// 计算最大值的位数
	maxDigit := 0
	for max > 0 {
		max = max/10
		maxDigit++
	}
	// 定义每一轮的除数,1,10,100...
	divisor := 1;
	// 定义了10个桶,为了防止每一位都一样所以将每个桶的长度设为最大,与原数组大小相同
	bucket := [10][20]int{{0}}
	// 统计每个桶中实际存放的元素个数
	count := [10]int{0}
	// 获取元素中对应位上的数字,即装入那个桶
	var digit int
	// 经过maxDigit+1次装通操作,排序完成
	for i := 1; i <= maxDigit; i++ {
		for j := 0; j < dataLen; j++ {
			tmp := data[j]
			digit = (tmp / divisor) % 10
			bucket[digit][count[digit]] = tmp
			count[digit]++
		}
		// 被排序数组的下标
		k := 0
		// 从0到9号桶按照顺序取出
		for b := 0; b < 10; b++ {
			if count[b] == 0 {
				continue
			}
			for c := 0; c < count[b]; c++ {
				data[k] = bucket[b][c]
				k++
			}
			count[b] = 0
		}
		divisor = divisor * 10
	}
	return data
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值