Go 语言算法之美—基础排序

开发 后端 算法
冒泡排序基于比较并交换,基本思路是遍历数据,如果相邻的元素大小不等,则交换它们的位置,如此循环往复,直到数据完全有序。

[[404642]]

本文转载自微信公众号「roseduan写字的地方」,作者roseduan。转载本文请联系roseduan写字的地方公众号。

录制 rosedb 视频的时候,挖了个坑,说要用 Go 语言实现常见的数据结构和算法,虽然现在这样的文章已经很多了,但是玫瑰哥??有坑必填!只能硬着头皮写了,这个系列,就叫做 Go 语言算法之美吧!

排序是一个十分古老的问题,也是计算机领域很经典的算法问题之一,后续的几篇文章,我将对常见的排序算法进行讲述。

我将会附上完整的代码,并且推荐一些相关的 Leetcode 题目,不仅可以用来学习巩固算法知识,还能够帮助你在面试当中,更加的游刃有余。

本篇文章介绍三种基础排序算法:冒泡排序、选择排序、插入排序。

冒泡排序

冒泡排序基于比较并交换,基本思路是遍历数据,如果相邻的元素大小不等,则交换它们的位置,如此循环往复,直到数据完全有序。

如下图,有测试数据 -2 45 0 11 -9。

在第一次遍历当中,会将数据中最大值 45 移动至末尾,然后在除了 45 的数据内再次遍历,将最大值移动至 45 之前。这样遍历完最后一个元素,数据即是有序的了。

下图比较直观的展示了冒泡排序的流程:

代码如下:

  1. func bubbleSort(data []int) { 
  2.    for i := 0; i < len(data); i++ { 
  3.       for j := 0; j < len(data)-i-1; j++ { 
  4.          if data[j] > data[j+1] { 
  5.             data[j], data[j+1] = data[j+1], data[j] 
  6.          } 
  7.       } 
  8.    } 

这里有一个小的优化点,如果数据本来就是有序的,例如 1 3 4 5 6 ,遍历一次之后,会发现没有任何数据进行交换,可以提前退出,不用继续进行遍历了,代码上可以进行优化,如下:

  1. func bubbleSort(data []int) { 
  2.    swap := true 
  3.    for i := 0; i < len(data) && swap; i++ { 
  4.       swap = false 
  5.       for j := 0; j < len(data)-i-1; j++ { 
  6.          if data[j] > data[j+1] { 
  7.             data[j], data[j+1] = data[j+1], data[j] 
  8.             swap = true 
  9.          } 
  10.       } 
  11.    } 

冒泡排序相关复杂度:

时间复杂度  
最坏 O(n2)
最好 O(n)
平均 O(n2)
空间复杂度 O(1)
是否稳定

选择排序

选择排序也很容易理解,对于一个无序的数组,我们每次都从数组中寻找最小值,并把它和第一个元素交换。

如下图,有测试数据 20 12 10 15 2,第一次遍历,寻找到最小值是 2:

并将其与数组的第一个元素进行交换:

然后在剩下的数据中继续寻找最小值,然后将其与数组第二个元素交换,如此循环往复,直到最后一个数据,这样整个数组便是有序的了。

下面这张动图可以帮助你理解选择排序的整个过程:

代码实现:

  1. func selectionSort(data []int) { 
  2.    for i := 0; i < len(data)-1; i++ { 
  3.       min := i 
  4.       for j := i + 1; j < len(data); j++ { 
  5.          if data[j] < data[min] { 
  6.             min = j 
  7.          } 
  8.       } 
  9.       data[i], data[min] = data[min], data[i] 
  10.    } 

选择排序相关复杂度:

时间复杂度  
最坏 O(n2)
最好 O(n2)
平均 O(n2)
空间复杂度 O(1)
是否稳定

插入排序

回想一下我们在玩纸牌游戏时,是如何将手中的纸牌变得有顺序的?当新来了一张纸牌,我们会在手中已有的纸牌中查找到合适的位置,将其插入。

插入排序也是这样的,依次遍历数组中的每一个数据,将其插入到合适的位置,下面的这张动图比较形象的说明了这个过程:

代码实现如下:

  1. func insertionSort(data []int) { 
  2.    for i := 0; i < len(data)-1; i++ { 
  3.       j, k := i+1, data[i+1] 
  4.       for ; j > 0 && data[j-1] > k; j-- { 
  5.          data[j] = data[j-1] 
  6.       } 
  7.       data[j] = k 
  8.    } 

插入排序相关复杂度:

时间复杂度  
最坏 O(n2)
最好 O(n)
平均 O(n2)
空间复杂度 O(1)
是否稳定

备注:完整代码我放到了我的 Github 上面,地址:

 

https://github.com/roseduan/Go-Algorithm

 

责任编辑:武晓燕 来源: roseduan写字的地方
相关推荐

2021-08-04 08:56:34

语言Go排序

2021-07-16 04:57:45

Go算法结构

2022-04-27 15:18:30

Go 语言API排序算法

2022-11-01 18:29:25

Go语言排序算法

2023-05-08 07:55:05

快速排序Go 语言

2022-05-07 08:55:11

Go语言排序算法

2022-04-06 08:58:39

归并排序Go算法

2021-02-06 18:19:54

TimeGo语言

2022-03-07 09:42:21

Go快速排序

2020-12-02 08:45:36

Go语言

2020-11-30 06:17:03

Go语言

2020-11-26 06:40:24

Go语言基础

2020-11-23 08:54:14

Go语言结构体

2023-12-30 10:22:57

Go语言函数开发

2021-01-19 07:02:26

算法数据结构堆排序

2024-01-07 19:54:51

2021-01-23 12:47:19

MySQL数据库Go语言

2021-11-05 22:47:44

冒泡排序选择插入

2020-12-16 08:07:28

语言基础反射

2020-11-05 09:58:16

Go语言Map
点赞
收藏

51CTO技术栈公众号