Go语言学习笔记【16】 排序算法之计数排序、算法总结

本文介绍了计数排序算法的原理、复杂度分析,并详细解释了基于队列数组和偏移地址的两种实现方式,适合Go语言学习者了解排序算法。
摘要由CSDN通过智能技术生成

【声明】

非完全原创,部分内容来自于学习其他人的理论。如果有侵权,请联系我,可以立即删除掉。

一、计数排序

1、方法和复杂度

1.1、核心思想和方法

计数排序是一个非基于比较的排序算法,对输入的数据有附加的限制条件:
1、输入的线性表的元素属于有限偏序集S;
2、设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n)。
在这两个条件下,计数排序的复杂性为O(n)。

计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。

1.2、稳定性

排序算法是稳定的,因为在确定最终有序序列而遍历原序列时,遍历的方式是自右往左,从而导致后面的元素一定是排在后面的(代码中会给出验证)

1.3、时间复杂度

时间复杂度为 O ( n + k ) O(n+k) O(n+k),其中n为要排序的元素个数,k为data中最大的整数加1

1.4、空间复杂度

空间复杂度为 O ( n + k ) O(n+k) O(n+k),其中n为要排序的元素个数,k为data中最大的整数加1

2、排序的过程

2.1、基于队列数组的方式

(1)初始化一个计数数组(若输入序列中的元素是整数,则数组的每一个元素存放的是序列中元素的计数值;若输入序列中的元素是其他类型,则数组的每一个元素存放的是一个队列),计数数组大小是输入序列的所有元素待排序字段中最大的数
(2)遍历输入序列,遇到一个元素,若输入序列是整数,则根据数值计数数组对应的位置上加一;若输入序列是其他类型,就根据元素待排序字段的值在计数数组中找到其索引,将元素放入到队列中
(3)依次从计数数组中取出元素,填充到数组中

如下图中,结构体元素的第一个字段为待排序字段(字段最大值是3),因此计数数组的长度为4(索引分别为0、1、2、3,由于2没有用到因此未画出来),每一个元素均为队列
过程

2.2、基于偏移地址的方式

见:排序算法的C语言实现(下 线性时间排序:计数排序与基数排序)

3、算法实现

package main

import "fmt"

const size = 10

type Data struct {
   
	No   int
	Name string
}

func Count(arr []*Data) {
   
	var index int = 0
	//记录输入序列中待排序字段的最大值
	var tmp_len int = 0
	for _, data := range arr {
   
		if tmp_len < data.No {
   
			tmp_len = data.No
		}
	}
	tmp_len++
	//创建数组,go不支持动态创建数组,因此用切片
	//队列用[]Data切片来表示,因为可以根据索引做到先进先出
	tmp_arr := make([][]*Data, tmp_len)
	for _, data := range arr {
   
		tmp_arr[data.No] = append(tmp_arr[data.No], data)
	}
	//按照数组的顺序取元素
	for i := 0; i < tmp_len; i++ {
   
		if tmp_arr[i] != nil {
   
			for j := 0; j < len(tmp_arr[i]); j++ {
   
				arr[index] = tmp_arr[i][j]
				index++
			}
		}
	}
	fmt.Println("【Count】排序, 最终结果: ")
	for i, data := range arr {
   
		fmt.Printf("i = %d, (%p)%v\n", i, data, *data)
	}
}

func main() {
   
	arr := [size]*Data{
   
		{
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值