Golang(二十四)[排序算法-计数排序]

在这里插入图片描述
计数排序/计数统计排序/变相插入排序

1.简介

计数排序(Counting sort) 是一种稳定的线性时间排序算法.计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C 来将A中的元素排到正确的位置。

2.原理

  • 找出待排序的数组中最大和最小的元素.
  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项.
  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加).
  • 反向填充目标数组:将每个元素 i放在新数组的第C[i]项,每放一个元素就将C[i]减去1.

3.操作规则

4.Golang代码

1.升序

// 计数排序--升序
func ContingSortAsc(slice []int) {
	// 创建map统计0-999每个数出现的次数
	m := make(map[int]int)
	// 遍历待排序的数据,统计结果
	for _, v := range slice {
		m[v]++
	}
	// 借助map,统计排序的数据重新赋值为原序列
	slice = slice[0:0] // 将原序列清空
	for i := 0; i < 1000; i++ {
		// for i := 0; i < 1000; i++ {
		// 数据出现的次数:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新赋值
		}
	}
}

2.降序

// 计数排序--降序
func ContingSortDesc(slice []int) {
	// 创建map统计0-999每个数出现的次数
	m := make(map[int]int)
	// 遍历待排序的数据,统计结果
	for _, v := range slice {
		m[v]++
	}
	// 借助map,统计排序的数据重新赋值为原序列
	slice = slice[0:0] // 将原序列清空
	for i := 999; i >= 0; i-- {
		// for i := 0; i < 1000; i++ {
		// 数据出现的次数:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新赋值
		}
	}
}

3.测试

func main() {
	slice := make([]int, 0)
	// 设置随机数种子
	rand.Seed(time.Now().UnixNano())
	// 生成100个1000以内的随机数
	for i := 1; i <= 100; i++ {
		slice = append(slice, rand.Intn(1000))
	}
	fmt.Println("原数据:", slice)
	ContingSortAsc(slice)
	fmt.Println("计数排序升序:", slice)
	ContingSortDesc(slice)
	fmt.Println("计数排序降序:", slice)
}

5.完整代码

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 计数排序--升序
func ContingSortAsc(slice []int) {
	// 创建map统计0-999每个数出现的次数
	m := make(map[int]int)
	// 遍历待排序的数据,统计结果
	for _, v := range slice {
		m[v]++
	}
	// 借助map,统计排序的数据重新赋值为原序列
	slice = slice[0:0] // 将原序列清空
	for i := 0; i < 1000; i++ {
		// for i := 0; i < 1000; i++ {
		// 数据出现的次数:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新赋值
		}
	}
}

// 计数排序--降序
func ContingSortDesc(slice []int) {
	// 创建map统计0-999每个数出现的次数
	m := make(map[int]int)
	// 遍历待排序的数据,统计结果
	for _, v := range slice {
		m[v]++
	}
	// 借助map,统计排序的数据重新赋值为原序列
	slice = slice[0:0] // 将原序列清空
	for i := 999; i >= 0; i-- {
		// for i := 0; i < 1000; i++ {
		// 数据出现的次数:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新赋值
		}
	}
}

func main() {
	slice := make([]int, 0)
	// 设置随机数种子
	rand.Seed(time.Now().UnixNano())
	// 生成100个1000以内的随机数
	for i := 1; i <= 100; i++ {
		slice = append(slice, rand.Intn(1000))
	}
	fmt.Println("原数据:", slice)
	ContingSortAsc(slice)
	fmt.Println("计数排序升序:", slice)
	ContingSortDesc(slice)
	fmt.Println("计数排序降序:", slice)
}

原数据: [657 58 694 781 52 352 755 659 335 929 815 957 919 537 861 70 249 746 88 485 456 414 13 378 911 173 252 182 716 248 15 581 508 469 112 83 427 950 995 4 420
256 134 405 746 246 584 174 203 923 742 76 627 643 405 285 262 363 657 673 629 247 891 668 478 253 131 6 215 72 36 785 546 614 586 187 157 394 867 579 786 697 773 116 397 642 186 900 850 624 982 580 890 952 816 748 595 33 978 946]
计数排序升序: [4 6 13 15 33 36 52 58 70 72 76 83 88 112 116 131 134 157 173 174 182 186 187 203 215 246 247 248 249 252 253 256 262 285 335 352 363 378 394 397 405
405 414 420 427 456 469 478 485 508 537 546 579 580 581 584 586 595 614 624 627 629 642 643 657 657 659 668 673 694 697 716 742 746 746 748 755 773 781 785 786 815 816 850 861 867 890 891 900 911 919 923 929 946 950 952 957 978 982 995]
计数排序降序: [995 982 978 957 952 950 946 929 923 919 911 900 891 890 867 861 850 816 815 786 785 781 773 755 748 746 746 742 716 697 694 673 668 659 657 657 643 642 629 627 624 614 595 586 584 581 580 579 546 537 508 485 478 469 456 427 420 414 405 405 397 394 378 363 352 335 285 262 256 253 252 249 248 247 246 215 203 187 186 182 174 173 157 134 131 116 112 88 83 76 72 70 58 52 36 33 15 13 6 4]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值