【Go笔记】第 8 章 排序和查找
Suriski 9/26/2022 韩顺平尚硅谷golang笔记
# 8.1 排序的基本介绍
排序是将一组数据,依指定的顺序进行排列的过程。 排序的分类:
- 内部排序: 指将需要处理的所有数据都加载到内部存储器中进行排序。 包括(交换式排序法、选择式排序法和插入式排序法);
- 外部排序法: 数据量过大,无法全部加载到内存中,需要借助外部存储进行 排序。包括(合并排序法和直接合并排序法)
冒泡排序(Bubble Sorting.)的基本思想是: 通过对待排序序列从后向前(从下标较大的元素开始),依次比较相 邻元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移向前部(从下标较大的单元移向下标较小的单元),就象水底下的气泡一样逐渐向上冒。因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较(优化)。
# 8.2 冒泡排序的思路分析
# 8.3 冒泡排序实现
package main
import (
"fmt”
)
//冒泡排序
func Bubblesort(arr *[5]int){
fmt.Println("排序前arr=”,(*arr))
temp :=0 //临时变量(用于做交换)
//冒泡排序..一步一步推导出来的
for i :=0;i<len(*arr)-1;i++{
for j:=0;j<len(*arr)-1-i;j++{
if (*arr)[j]>(*arr)[j+1] {
//交换
temp = (*arr)[j]
(*arr)[j] = (*arr)[j+1]
(*arr)[j+1] = temp
}
}
}
fmt.Println("排序后arr=",(*arr))
}
func main() {
//定义数组
arr:=[5]int{24,69,80,57,13}
//将数组传递给一个函数,完成排序
Bubblesort(&arr)
fmt.Println("main arr=",arr) //有序?是有序的
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 8.4 课后练习
略
# 8.5 查找
🏷 介绍: 在 Golang 中,我们常用的查找有两种:
- 顺序查找
- 二分查找(该数组是有序)
🏷 案例演示:
- 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王 猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】 代码:
package main
import(
"fmt"
)
func main(){
//有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼幅王
//猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
//思路
//1定义一个数组,白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王字符串数组
//2.从控制台接收一个名字,依次比较,如果发现有,提示
//1代码
names := [4]string("白眉鹰王”,“金毛狮王",“紫衫龙王”,"青翼蝠王"}
var heroName = ""
fmt.Println("请输入要查找的人名..")
fmt.Scanln(&heroName)
//顺序查找:第一种方式
for i :=0;i<len(names);i++{
if heroName == names[i] {
fmt.Printf("找到%v,下标%v\n”,heroName,i)
break
}else if i==(len(names)-1){
fmt.Printf("没有找到%w\n”,heroName)
}
}
//顺序查找:第2种方式(推荐.·)
index := -1
for i:=0;i<len(names);i++{
if heroName ==names[i] {
index=i//将找到的值对应的下标赋给 index
break
}
}
if index !=-1{
fmt.Printf("找到%v,下标%vn”,heroName,index)
}else{}
fmt.Println("没有找到",heroName)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- 请对一个 有序数组进行二分查找 {1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。【会使用到递归】 二分查找的思路分析:
二分查找的代码实现:
package main
import (
"fmt"
)
//二分查找的函数
/*
二分查找的思路: 比如我们要查找的数是 findVal1. arr 是一个有序数组,并且是从小到大排序
2. 先找到 中间的下标 middle = (leftIndex + rightIndex) / 2, 然后让 中间下标的值和 findVal 进行
比较
2.1 如果 arr[middle] > findVal , 就应该向 leftIndex ---- (middle - 1)2.2 如果 arr[middle] < findVal , 就应该向 middel+1---- rightIndex2.3 如果 arr[middle] == findVal , 就找到
2.4 上面的 2.1 2.2 2.3 的逻辑会递归执行
3. 想一下,怎么样的情况下,就说明找不到[分析出退出递归的条件!!]
if leftIndex > rightIndex {
// 找不到..
return ..
}
*/
func BinaryFind(arr *[6]int, leftIndex int, rightIndex int, findVal int) {
//判断 leftIndex 是否大于 rightIndex if leftIndex > rightIndex {
fmt.Println("找不到")
return
}
//先找到 中间的下标
middle := (leftIndex + rightIndex) / 2
if (*arr)[middle] > findVal {
//说明我们要查找的数,应该在 leftIndex --- middel-1 BinaryFind(arr, leftIndex, middle-1, findVal)
} else if (*arr)[middle] < findVal {
//说明我们要查找的数,应该在 middel+1 --- rightIndex BinaryFind(arr, middle+1, rightIndex, findVal)
} else {
//找到了
fmt.Printf("找到了,下标为%v \n", middle)
}
}
func main() {
arr := [6]int{1, 8, 10, 89, 1000, 1234}
//测试一把
BinaryFind(&arr, 0, len(arr)-1, -6)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 8.6 二维数组的介绍
多维数组我们只介绍二维数组
# 8.7 二维数组的应用场景
比如我们开发一个五子棋游戏,棋盘就是需要二维数组来表示。如图
# 8.8 二维数组快速入门
快速入门案例: 🏷 请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
🏷 代码演示
package main
import "fmt"
func main() {
//1二维数组的演示案例
/**
000g00 001000 020300 000000 **/ //定义/声明二维数组
var arr [4][6]int
//1赋初值
arr[1][2] = 1
arr[2][1] = 2
arr[2][3] = 3
//遍历二维数组,按照要求输出图形
for i := 0; i < 4; i++ {
for j := 0; j < 6; j++ {
fmt.Print(arr[i][j], "")
}
fmt.Println()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 8.9 使用方式 1: 先声明/定义,再赋值
🏷 语法: var 数组名 [大小][大小]类型
🏷 比如: var arr [2][3]int
, 再赋值。
🏷 使用演示
🏷 二维数组在内存的存在形式(重点)
var arr2[2][3]int //以这个为例来分析arr2在内存的布局1I
arr2[1][1]=10
fmt.Println(arr2)
fmt.Printf("arr2[o]的地址%pn",&arr2[o])
fmt.Printf("arr2[1]的地址%p\n",&arr2[1])
fmt.Printf("arr2[o][o]的地址%p\n",&arr2[o][o])
fmt.Printf("arr2[1][o]的地址%pn”,&arr2[1][o])
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 8.10 使用方式 2: 直接初始化
🏷 声明:
var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
1
🏷 赋值(有默认值,比如 int 类型的就是 0) 🏷 使用演示
fmt.Println()
var arr3[2][3]int=[2][3]int{[1,2,3},{4,5,6}}
fmt.Println("arr3=",arr3)
1
2
3
2
3
说明:二维数组在声明/定义时也对应有四种写法[和一维数组类似]
var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 [大小][大小]类型 = [...][大小]类型{{初值..},{初值..}}
var 数组名 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 = [...][大小]类型{{初值..},{初值..}}
1
2
3
4
5
2
3
4
5
# 8.11 二维数组的遍历
🏷 双层 for 循环完成遍历 🏷 for-range 方式完成遍历 案例演示:
package main
import "fmt"
func main() {
//演示二维数组的遍历
var arr3 = [2][3]int{{1, 2, 3}, {4, 5, 6}}
//for循环来遍历
for i := 0; i < len(arr3); i++ {
for j := 0; j < len(arr3[i]); j++ {
fmt.Printf("%v\t", arr3[i][j])
}
fmt.Println()
}
//for-range来遍历二维数组
for i, v := range arr3 {
for j, v2 := range v {
fmt.Printf("arr3[%v][%v]=%v \t", i, j, v2)
}
fmt.Println()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 8.12 二维数组的应用案例
🏷 要求如下: 定义二维数组,用于保存三个班,每个班五名同学成绩, 并求出每个班级平均分、以及所有班级平均分 🏷 代码
package main
import "fmt"
func main() {
/**
定义二维数组,用于保存三个班,每个班五名同学成绩,
并求出每个班级平均分、以及所有班级平均分
*/ //1.定义一个二维数组
var scores [3][5]float64
//2,循环的输入成绩
for i := 0; i < len(scores); i++ {
for j := 0; j < len(scores[i]); j++ {
fmt.Printf("请输入第%d班的第%d个学生的成绩\n", i+1, j+1)
fmt.Scanln(&scores[i][j])
}
} //fmt.Println(scores)
//3.遍历输出成绩后的二维数组,统计平均分
totalsum := 0.0 // 定义一个变量,用于累计所有班级的总分
for i := 0; i < len(scores); i++ {
sum := 8.0 //定义一个变量,用于累计各个班级的总分
for j := 0; j < len(scores[i]); j++ {
sum += scores[i][j]
}
totalsum += sum
fmt.Printf("第%d班级的总分为%v,平均分%v\n", i+1, sum, sum/float64(len(scores[i])))
}
fmt.Printf("所有班级的总分为%v,所有班级平均分%v\n",
totalsum, totalsum/15)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31