实战|从零实现一个排序算法,使用Go语言输出缩排格式

简介: 实战|从零实现一个排序算法,使用Go语言输出缩排格式

/ Go 语言实现缩排排序(Indent Sort) /

缩排排序是一种简单有趣的排序算法。它通过递归地扫描输入,产生缩排格式的输出,从而完成排序。本文将通过示例详细介绍如何使用 Go 语言实现缩排排序。

主要内容包括:

  1. 算法原理
  2. 简单实现
  3. 递归实现
  4. 优化递归
  5. 测试程序
  6. 改进扩展

希望本文可以增进大家对递归算法和排序方法的理解,并练习 Go 语言编码能力。实现一个排序算法并不复杂,但需要正确的递归思维。

1

 

1. 算法原理

缩排排序的基本思路是:

  1. 查找最小值,输出
  2. 递归对剩余元素排序,并缩排一个空格
  3. 这样递归处理所有元素,直到全部输出排序

比如输入 [5, 3, 6, 2, 1]

找到最小 1 输出,剩余 [5, 3, 6, 2] 递归排序:

/ Go 语言实现缩排排序(Indent Sort) /
缩排排序是一种简单有趣的排序算法。它通过递归地扫描输入,产生缩排格式的输出,从而完成排序。本文将通过示例详细介绍如何使用 Go 语言实现缩排排序。
主要内容包括:
算法原理
简单实现
递归实现
优化递归
测试程序
改进扩展
希望本文可以增进大家对递归算法和排序方法的理解,并练习 Go 语言编码能力。实现一个排序算法并不复杂,但需要正确的递归思维。
1
1. 算法原理
缩排排序的基本思路是:
查找最小值,输出
递归对剩余元素排序,并缩排一个空格
这样递归处理所有元素,直到全部输出排序
比如输入 [5, 3, 6, 2, 1]
找到最小 1 输出,剩余 [5, 3, 6, 2] 递归排序:

再后续递归,直到全部元素输出,形成缩排格式的有序序列。

2

 

2. 简单实现

首先,一个简单的递归实现是:

func indentSort(nums []int) {
  if len(nums) == 0 {
    return 
  }
  min := findMin(nums)
  fmt.Println(min)
  indentSort(remove(nums, min))
  fmt.Print(" ")
}

主要步骤是:

  1. 找最小值并输出
  2. 递归排序剩余 slice,并打印空格

这实现了基本的缩排排序。

3

 

3. 递归实现

我们将递归排序封装成一个函数:

func sort(nums []int) {
  if len(nums) == 1 {
    fmt.Println(nums[0])
    return
  }
  min := findMin(nums)
  fmt.Println(min)
  sort(remove(nums, min)) // 递归排序
  fmt.Print(" ")  
}

递归出口是 slice 长度为 1 时,打印这个数,不再递归。

4

 

4. 优化递归

我们可以做一些优化:

  1. 利用 append 实现 slice 删除,不需要从新分配内存
func remove(nums []int, val int) []int {
  result := append(nums[:i], nums[i+1:]...)
  return result
}

引入一个 indent 变量表示当前缩排大小,格式化输出

func sort(nums []int, indent int) {
  fmt.Println(strings.Repeat(" ", indent), min)
  sort(nums, indent+1) // 递增缩排值
  fmt.Print(strings.Repeat(" ", indent), " ")
}

这样可以使输出格式更好。

5

 

5. 测试

为了测试程序,我们可以添加一些测试用例:

func TestIndentSort(t *testing.T) {
  nums := []int{5, 3, 8, 2}
  got := indentSort(nums) // 获取排序结果
  expected := []int{2, 3, 5, 8}
  if !reflect.DeepEqual(got, expected) {
    t.Errorf("expected %v, got %v", expected, got)
  }
}

添加一些基本用例可以验证程序正确性。

6

 

6. 改进扩展

可以从以下几个方向改进程序:

  • 支持不同类型的输入
  • 测试更多复杂输入
  • 计算时间和空间复杂度
  • 和其他排序算法比较效率
  • 增加并发改进性能

一些扩展练习:

  • 实现一个通用的递归排序函数
  • 支持排序自定义数据类型
  • 输出排序的每个步骤变化
  • 可视化递归排序过程

7

 

总结

缩排排序是一个有趣的算法,通过本文的讲解和代码实现,可以加深对递归和排序算法的理解,并练习 Go 语言编码能力。可以继续扩展程序,实现更多功能。


目录
相关文章
|
9天前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
6天前
|
存储 NoSQL 算法
实战算法篇:设计短域名系统,将长URL转化成短的URL.
小米介绍了一种实用的短域名系统设计,用于将冗长的URL转化为简短链接。短链接不仅节省空间,便于分享,还能支持数据分析。系统通过唯一编号结合62进制转换生成短标识,并利用如Redis这样的数据库存储长链接与短标识的映射关系。最后,通过302重定向实现用户访问时的长链接恢复。这一方案适用于多种场景,有效提升用户体验与数据追踪能力。
22 9
|
2天前
|
安全 Java Go
探索Go语言在高并发环境中的优势
在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
|
6天前
|
运维 Kubernetes Go
"解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
27 1
|
6天前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
15 1
|
12天前
|
XML JSON Go
微服务架构下的配置管理:Go 语言与 yaml 的完美结合
微服务架构下的配置管理:Go 语言与 yaml 的完美结合
|
6天前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
7天前
|
JSON 缓存 监控
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
Viper 是一个强大的 Go 语言配置管理库,适用于各类应用,包括 Twelve-Factor Apps。相比仅支持 `.ini` 格式的 `go-ini`,Viper 支持更多配置格式如 JSON、TOML、YAML
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
|
8天前
|
安全 Go API
go语言中的Atomic操作与sema锁
在并发编程中,确保数据一致性和程序正确性是关键挑战。Go语言通过协程和通道提供强大支持,但在需精细控制资源访问时,Atomic操作和sema锁变得至关重要。Atomic操作确保多协程环境下对共享资源的访问是不可分割的,如`sync/atomic`包中的`AddInt32`等函数,底层利用硬件锁机制实现。sema锁(信号量锁)控制并发协程数量,其核心是一个uint32值,当大于零时通过CAS操作实现锁的获取与释放;当为零时,sema锁管理协程休眠队列。这两种机制共同保障了Go语言并发环境下的数据完整性和程序稳定性。
|
9天前
|
算法 Go
Go 语言 实现冒泡排序
冒泡排序是大家熟知的经典算法。在Go语言中实现它,关键在于理解其核心思想:通过不断比较并交换相邻元素,让序列中的最大值像泡泡一样“浮”至顶端。每一轮比较都能确定一个最大值的位置。外层循环控制排序轮数,内层循环负责比较与交换。随着每轮排序完成,未排序部分逐渐缩小,直至整个数组有序。以下是Go语言实现示例及说明。
17 1