clllll  

计数排序

  1. 新创建一个计数数组,size=Max
  2. 遍历数组, 值是索引。
  3. 遍历计数数组,依次排列。
func CountSort(arr []int) {

	count_arr := make([]int, 10)
	for _, value := range arr {
		count_arr[value]++
	}
	i := 0
	for index, value := range count_arr {
		for value > 0 {
			arr[i] = index
			i++
			value--
		}
	}
}

基数排序(桶排序)

image

import (
	"fmt"
	"math"
)

func RadixSort(arr []int) {

	// //初始化10个桶, 0-9 //在这里初始化错了。要么就for循环重置桶。
	// bucket := make([][]int, 10) //如果是其他进制数 ,就以其它进制数的个数来初始化。
	// fmt.Println(bucket)

	// 最高位
	max_bit := 3 // 可以先遍历一遍数组,得到最大值,然后计算其位数。这里就以三位数来。

	// 最外层循环,从个位 1到最高位 百位 3

	for d := 1; d <= max_bit; d++ {
		//初始化10个桶, 0-9
		bucket := make([][]int, 10) //如果是其他进制数 ,就以其它进制数的个数来初始化。
		fmt.Println(bucket)

		//遍历当前位的数,然后放进自己的桶中,入桶
		for _, value := range arr {
			mi := math.Pow(10, float64(d-1))
			// fmt.Println(mi)
			current_d := value / int(mi) % 10
			fmt.Println(d, value, current_d)
			bucket[current_d] = append(bucket[current_d], value)

		}
		fmt.Println(d, "入桶", bucket)
		// 出桶
		c := 0
		for i := 0; i < len(bucket); i++ {
			for j := 0; j < len(bucket[i]); j++ {
				arr[c] = bucket[i][j]
				c++
			}
		}
		fmt.Println(d, "出桶", arr)
	}
}

错误点:桶初始化的位置不对,每次for循环要重新初始化。

基数排序优化

就是使用词频统计,当前位前面有多少个数,从右到左还原数组。

package basicsort

import (
	"fmt"
	"math"
)

func RadixSort02(arr []int) {

	// 最高位
	max_bit := 3 // 可以先遍历一遍数组,得到最大值,然后计算其位数。这里就以三位数来。

	// 最外层循环,从个位 1到最高位 百位 3

	for d := 1; d <= max_bit; d++ {
		// 当前位 数字 词频统计
		count := [10]int{}

		// help数组,和当前数组一致
		help := make([]int, len(arr)) //这里得用make, 不能用 []int{}.会报index out of range

		//遍历当前位的数,然后放进自己的桶中,入桶
		for _, value := range arr {
			mi := math.Pow(10, float64(d-1))
			// fmt.Println(mi)
			current_d := value / int(mi) % 10
			fmt.Println(d, value, current_d)
			count[current_d]++
		}
		fmt.Println(d, "count", count)

		// 计算 当前 i位置前面有多少个说

		for i := 1; i < len(count); i++ {
			count[i] = count[i] + count[i-1]
		}
		fmt.Print("前面有多少个", count)

		//从右到左遍历
		for i := len(arr) - 1; i >= 0; i-- {
			value := arr[i]
			mi := math.Pow(10, float64(d-1))
			current_d := value / int(mi) % 10

			tmp_index := count[current_d]
			count[current_d]--
			help[tmp_index-1] = value //这里要减一, 比如前面有7个,索引是6
		}
		fmt.Print("help:", help)
		copy(arr, help)
		fmt.Print("arr:", arr)
	}
}

总结

这种不使用比较大小来排序的方式对数据有要求。必须是进制数。不能是其他对象。
计数排序,数的范围太大,开辟的内存就大,不好。

posted on 2023-01-22 20:42  llcl  阅读(65)  评论(0编辑  收藏  举报