【Go】C++转Go:数据结构练习(一)排序算法

本专栏文章持续更新,新增内容使用蓝色表示。

每种排序方法都可以通过例子,手动模拟一遍,确定思路,再开始写代码。

持续更新中,预计1-2天内完善

冒泡排序

描述:

通过相邻元素的比较和交换,使较大的元素逐渐"浮"到数组的末尾,就像水中的气泡一样向上漂浮。

思路:

举一个实例,如有一个数组 {9,2,10,23,16,28,2} ,将它从小到大排序。

第一轮,从第0和第1个元素开始比较,9>2交换,9<10跳过,10<23跳过,23>16交换,23<28跳过,28>2交换,此时整个数组中最大的元素在末尾,再次遍历时就不需要和末尾的元素比较。末尾一个元素固定,此时的数组为{2,9,10,16,23,2,28} 。

第二轮,依旧从第0和第1个元素开始比较,2<9跳过 9<10跳过 10<16跳过 16<23跳过 23>2交换。末尾两个元素固定,此时的数组为{2,9,10,16,2,23,28} 。

第三轮,2<9跳过 9<10跳过 10<16跳过 16>2交换。末尾三个元素固定,此时的数组为{2,9,10,2,16,23,28} 。

第四轮,2<9跳过 9<10跳过 10>2交换。末尾四个元素固定,此时的数组为{2,9,2,10,16,23,28} 。

第五轮,2<9跳过 9>2交换 。末尾五个元素固定,此时的数组为{2,2,9,10,16,23,28} 。

第六轮,2==2跳过 。末尾六个元素固定,此时的数组为{2,2,9,10,16,23,28} 。

综上,整个过程中给7个元素排序,需要经过6轮。

如果是{1, 2, 3, 4, 5, 7, 6}呢?同样是7个元素,但是实际上在第2轮时,就已经有序,没有进行交换了。所以可以设置一个标志位flag,每轮进入时设为false,有交换时置为true,如果该轮结束该值为false,说明没有发生交换,数组已经有序,程序可以提前跳出循环。

Go 复制代码
package main

import "fmt"

func PrintNums(nums []int) {
	for i := 0; i < len(nums); i++ {
		fmt.Printf("%d ", nums[i])
	}
	fmt.Println()
}

func main() {
	// 冒泡排序
	nums := []int{9, 2, 10, 23, 16, 28, 2}
	fmt.Printf("原数组:")
	PrintNums(nums)
	fmt.Printf("冒泡排序过程:\n")
	for i := 0; i < len(nums)-1; i++ {
		flag := false
		for j := 0; j < len(nums)-i-1; j++ {
			if nums[j] > nums[j+1] {
				flag = true
				temp := nums[j]
				nums[j] = nums[j+1]
				nums[j+1] = temp
			}
		}
		PrintNums(nums)
		if flag == false {
			fmt.Println("本轮无交换,已提前结束!")
			break
		}
	}
}

时间复杂度最差为O(),最好为O(n),平均时间复杂度为O()。

空间复杂度为O(1),不需要借助额外数组。

选择排序

描述:

每轮选择一个最大或者最小的数,放在已排序元素的末尾。

思路:

还是数组 {9,2,10,23,16,28,2} ,将它从小到大排序。先尝试选择一个最小的数,放在已排序元素的末尾。假设已排序元素在前面,初始情况下已排序元素个数为0,已排序指针为0,数组指针为0。从0开始遍历。

第一轮,从0开始,到6结束,发现最小的是2,下标为1,进行交换,已排序元素为1。

以此类推,已排序元素逐渐增多,7个元素共经历6轮成为有序数组。

Go 复制代码
package main

import "fmt"

func PrintNums(nums []int) {
	for i := 0; i < len(nums); i++ {
		fmt.Printf("%d ", nums[i])
	}
	fmt.Println()
}

func main() {
	nums := []int{9, 2, 10, 23, 16, 28, 2}
	fmt.Printf("原数组:")
	PrintNums(nums)
	fmt.Printf("选择排序过程:\n")
	for i := 0; i < len(nums)-1; i++ {
		minnum := i
		for j := i; j < len(nums); j++ {
			if nums[minnum] > nums[j] {
				minnum = j
			}
		}
		temp := nums[i]
		nums[i] = nums[minnum]
		nums[minnum] = temp
		PrintNums(nums)
	}
}

插入排序

描述:

在已排序的数组中选择一个合适的位置插入进去,从后往前比较。

思路:

数组 {9,2,10,23,16,28,2} ,单独一个数字必然是有序的,所以跳过0号位置,从1号位置开始,依次和前面已有序的数组进行比较,若小于,则交换,否则跳过。

Go 复制代码
package main

import "fmt"

func PrintNums(nums []int) {
	for i := 0; i < len(nums); i++ {
		fmt.Printf("%d ", nums[i])
	}
	fmt.Println()
}

func main() {
	nums := []int{9, 2, 10, 23, 16, 28, 2}
	fmt.Printf("原数组:")
	PrintNums(nums)
	fmt.Printf("插入排序过程:\n")
	for i := 0; i < len(nums)-1; i++ {
		for j := i + 1; j > 0; j-- {
			if nums[j] < nums[j-1] {
				temp := nums[j]
				nums[j] = nums[j-1]
				nums[j-1] = temp
			} else {
				break
			}
		}
		PrintNums(nums)
	}
}

剩下的后续更新

预计明天

希尔排序

插入排序的plus版本,将原始列表分成多个子列。

归并排序

描述:

分而治之

快速排序

描述:

选择一个基准元素与之比较,大于它的都放在后面,小于等于它的都放在前面,然后再递归的对前后进行处理。

堆排序

基数排序

相关推荐
不许哈哈哈2 小时前
Python数据结构
数据结构·算法·排序算法
a***56063 小时前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
sin_hielo4 小时前
leetcode 2872
数据结构·算法·leetcode
AI科技星5 小时前
为什么宇宙无限大?
开发语言·数据结构·经验分享·线性代数·算法
合方圆~小文6 小时前
AI摄像头精准识别技术依赖于深度算法
数据结构·数据库·数码相机·模块测试
松涛和鸣6 小时前
16、C 语言高级指针与结构体
linux·c语言·开发语言·数据结构·git·算法
小欣加油10 小时前
leetcode 1018 可被5整除的二进制前缀
数据结构·c++·算法·leetcode·职场和发展
无敌最俊朗@10 小时前
链表-力扣hot100-随机链表的复制138
数据结构·leetcode·链表
未来之窗软件服务10 小时前
幽冥大陆(三十五)S18酒店门锁SDK go语言——东方仙盟筑基期
java·前端·golang·智能门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk
0***863311 小时前
【Golang】——Gin 框架中的表单处理与数据绑定
microsoft·golang·gin