为了账号安全,请及时绑定邮箱和手机立即绑定

用Go语言轻松掌握排序算法:新手入门搞定小型数据集排序

算法
算法是编程解决问题的关键。不论是管理任务、地图上寻找最快的路线,还是简单来说对名字列表进行排序,算法都会发挥作用。在软件开发领域,理解算法对于编写高效的、可扩展的和容易维护的代码非常重要。

在这篇文章中,我们将重点关注一个最基本和最核心的算法挑战——对小数据集进行排序。我们将看看如何用 Go 语言实现排序算法,并了解它们在实际中的应用。

算法1

为什么我们要讨论这个主题

排序数据是开发人员经常需要处理的一项常见任务。从排名搜索结果到组织用户数据,高效的排序算法可以显著地影响应用程序的性能。对于初学者来说,学习排序算法可以为他们打下坚实的基础,帮助理解更复杂的算法思想。

但这里有一个有趣的问题:假如你在处理一个较小的数据集的情况下,性能依然很重要呢?想象一下,你正在为一场本地的黑客松开发一个排行榜功能,排名必须实时更新。你需要一个既简单又高效的排序解决方案。这篇文章就是为此而写的。

1. 快速排序

以下代码实现了一个用于本地黑客松的动态排名榜。它使用高效排序算法和其他实用的函数来处理实时的更新。

    // QuickSort 对参赛者切片按分数降序进行排序。
    // 它采用分治法进行高效排序。
    //
    func QuickSort(participants []models.Participant, low, high int) {
        if low < high {
            // 找到分割点的位置
            p := partition(participants, low, high)
            // 递归地对左右子切片进行排序
            QuickSort(participants, low, p-1)
            QuickSort(participants, p+1, high)
        }
    }

全屏模式,点击这里进入,点击这里退出

输入: 参与者片段,以及当前排序范围的起始和结束索引。
输出: 切片会按降序排列。
它是如何工作的:

  1. 调用分区函数将一个元素(枢轴)放到其正确的位置。
  2. 递归对枢轴两边的数组进行排序。

2. 分区函数

    // 分区会重新排列 slice,使得所有大于或等于 pivot 的元素位于 pivot 之前,所有小于 pivot 的元素位于 pivot 之后。
    func partition(participants []models.Participant, low, high int) int {
        pivot := participants[high].Score // 将 pivot 设为最后一个元素
        i := low - 1                      // 初始化指针,用于标记大于或等于 pivot 的元素

        for j := low; j < high; j++ {
            // 如果当前元素的分数大于或等于 pivot,
            if participants[j].Score >= pivot {
                i++ // 将指针移动一位
                // 将当前元素与指针 i 所指向的元素交换
                participants[i], participants[j] = participants[j], participants[i]
            }
        }

        // 最后,将 pivot 放在正确的位置上
        participants[i+1], participants[high] = participants[high], participants[i+1]
        return i + 1 // 返回 pivot 的位置索引
    }

全屏/退出全屏

此功能确保元素的顺序被正确调整。

  • 较大的数放在基准的左边。
  • 较小的数放在基准的右边。

返回该数组的枢轴索引,该索引将其划分为两部分,以便进行进一步排序。

3. 更新分数.

    // UpdateScore 根据名字更新参赛者的分数。
    // 如果未找到参赛者,则打印一条消息。
    func UpdateScore(participants []models.Participant, name string, newScore int) {
        for i := range participants {
            // 按名字查找参赛者
            if participants[i].Name == name {
                // 更新他们的分数
                participants[i].Score = newScore
                return
            }
        }
        fmt.Println("未找到该参赛者!")
    }

切换到全屏模式 退出全屏

目的: 快速更新参赛者的得分。
流程:

  • 首先,遍历参与者列表。其次,如果找到匹配的名称(Name == name),则更新该参与者的Score。
  • 再次,如果没有找到匹配项,打印一条有用的提示信息。

4. 显示排行榜页面.

// 显示排行榜,按排名顺序打印参与者。
func DisplayLeaderboard(participants []models.Participant) {
    fmt.Println("\n--- 黑客马拉松排行榜 ---")
    for i, participant := range participants {
        // 输出每个参与者的名次、姓名和分数
        fmt.Printf("%d. %s - %d\n", i+1, participant.Name, participant.Score)
    }
}

全屏 退出全屏

目的: 显示当前排名榜的最新状态。
工作原理:

  • 遍历排序后的切片,输出每个元素。
  • 以易读的格式打印排名、参赛者名字和得分。

5. 添加新成员

    // 添加参与者 如果该名字不存在于参与者列表中,则添加新参与者。
    func AddParticipant(participants []models.Participant, name string, score int) ([]models.Participant, error) {
        // 检查是否已有该参与者
        if CheckIfParticipantExists(participants, name) {
            return participants, fmt.Errorf("参与者 %s 已存在于列表中", name)
        }
        // 添加新参与者
        participants = append(participants, models.Participant{Name: name, Score: score})
        return participants, nil
    }

全屏 退出全屏

  • 确保排名列表中没有重复的名字。
  • 如果参与者尚不存在,则将其追加到列表中并返回更新后的列表。

6. 是否已有该参与者

    // 检查给定名称的参与者是否存在列表中
    func 检查参与者是否存在(participants []models.Participant, name string) bool {
        // 检查给定名称的参与者是否存在
        for _, p := range participants {
            if p.Name == name {
                return true
            }
        }
        return false
    }

全屏,退出全屏

  • 一个帮助函数,用于检查参赛者名称是否已存在排行榜中。

7. 主界面的示例工作流程

    func main() {
        // 初始化参与者
        participants := []models.Participant{
            {Name:"Alice",Score: 85},
            {Name:"Bob",Score: 70},
            {Name:"Charlie",Score: 90},
        }

        // 添加新参与者
        participants, _ = AddParticipant(participants, "Diana", 75)

        // 把Bob的分数改为95
        UpdateScore(participants, "Bob", 95)

        // 排序排名
        QuickSort(participants, 0, len(participants)-1)

        // 显示排名
        DisplayLeaderboard(participants)
    }

全屏 开启/关闭

如果你想看看完整的代码实现,并亲自试一试,可以在我的GitHub仓库里找到该项目 Dynamic-Leaderboard。欢迎克隆下来并试着玩一玩这些算法!
编程愉快!🎉

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消