冒泡排序
- 重点,众多面试都考察冒泡排序
- 冒泡排序的基本思想:通过对 待排序序列从后向前(从下标大的元素开始),一次比较相邻的元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移向。
- 因为排序过程中,各元素不断接近自己位置,如果一趟下来没有进行交换,说明序列有序,因此优化时 要在排序过程中设置一个标志flag判断元素是否进行交换,从而减少不必要的比较。
冒泡排序详细分解剖析
-
首先要存在一个数组或者切片
-
已定义的数组:
//方式1 var array [n]int = [n]int{xx,xx,xx,...} //方式2 var array = [...]int{xx,xx,xx,...} //方式3 var array = make([]int,n)
-
外部传入数字形成数组
var n int = 0 //统计元素个数 fmt.Println("请输入数组的元素个数: ") fmt.Scanf("%d", &n) var arr []int = make([]int, n) //定义一个空切片,len为n for i := 0; i < n; i++ { var n1 int fmt.Printf("请输入第%d个元素的值:", i+1) fmt.Scanf("%d", &n1) //每个值都是切片中的一个值 arr[i] = n1 //赋值完毕 }
-
-
为了代码复用,写一个可以被调用的函数,命名为 bubbleSort(arr *[]int),要注意的是本函数传参一定要使用引用传递,通过本函数修改main()中的arr变量,所以需要传递指针类型变量。
func bubbleSort(arr *[]int) { temp := 0 //定义一个中间变量当做交换值传递媒介 for i := 0; i < len(*arr)-1; i++ { //外循环为确定最值的循环次数,所以为(数组元素-1)次 for j := 0; j < len(*arr)-1-i; j++ { //内循环次数为元素两两交换次数,由于每外循环一次,最元素就不用再次比较,所以可以减少一次比较,随着外循环次数上升而减少 if (*arr)[j] < (*arr)[j+1] { //元素j < 元素j+1 就交换,最后就是降序排列; temp = (*arr)[j] //元素j > 元素j+1就交换,那么就是升序排列。 (*arr)[j] = (*arr)[j+1] (*arr)[j+1] = temp } } } }
最终代码如下:
package main
import "fmt"
func bubbleSort(arr *[]int) {
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
}
}
}
}
func main() {
/*
构建一个切片
*/
var n int
fmt.Println("请输入切片的元素个数: ")
fmt.Scanf("%d", &n)
var arr []int = make([]int, n)
for i := 0; i < n; i++ {
var n1 int
fmt.Printf("请输入第%d个元素的值:", i+1)
fmt.Scanf("%d", &n1)
arr[i] = n1
}
fmt.Println(arr)
/*
开始冒泡排序算法,从小到大排列(升序),从大到小排列(降序)
*/
bubbleSort(&arr)
fmt.Println(arr)
}
顺序查找
顺序查找举例:
第一种方式:太啰嗦
package main
import "fmt"
func main() {
var arr = [...]string{"主宰","美杜莎","幻影刺客","杨叫兽"}
var heroName string
fmt.Println("请输入你要查找的对象: ")
fmt.Scanf("%v",&heroName)
for i := 0 ; i < len(arr) ; i++ {
if heroName == arr[i] {
fmt.Printf("找到%v,下标为%v",heroName,i)
break
} else if i == len(arr) - 1 {
fmt.Printf("没有找到%v",heroName)
}
}
}
第二种方式:下标改变即证明找到(推荐)
package main
import "fmt"
func main() {
var arr = [...]string{"主宰","美杜莎","幻影刺客","杨叫兽"}
var heroName string
fmt.Println("请输入你要查找的对象: ")
fmt.Scanf("%v",&heroName)
index := -1
for i := 0 ; i < len(arr) ; i++ {
if heroName == arr[i] {
index = i
break
}
}
if index != -1 {
fmt.Printf("找到%v,下标为%v",heroName,index)
} else {
fmt.Printf("没有找到%v",heroName)
}
}
二分查找
-
重点,众多面试都考察二分查找
-
二分查找的基本思想:首先数组一定要有序,这是进行二分查找的必要条件。
-
二分查找的原理:求有序数列 两个最值leftindex&rightindex之和/2 得到一个middle的下标,通过middle下标的值和查找值比较,得到下面两种结果扩展:
-
数组从小到大排列
arr[middle] > findVal :递归查找结果范围变成 leftindex ~ middle - 1
arr[middle] < findVal: 递归查找结果范围变成 middle + 1 ~ rightindex
arr[middle] = findVal: 正好,一次性就找到了
leftindex == rightindex : 最后一次比较
leftindex > rightindex :找不到 -
数组从大到小排列
arr[middle] > findVal :递归查找结果范围变成 middle + 1 ~ rightindex
arr[middle] < findVal: 递归查找结果范围变成 leftindex ~ middle - 1
arr[middle] = findVal: 正好,一次性就找到了
leftindex == rightindex : 最后一次比较
leftindex > rightindex :找不到 -
上述两种比较方式也就诠释了为何二分查找比顺序查找快很多,因为不断二分二分迅速完成查找。
-
最终代码如下:
package main
import "fmt"
func binaryFind(slice *[]int,leftin int,rightin int,findVal int) {
midin := (leftin + rightin) / 2
if leftin > rightin {
fmt.Println("查找的内容不存在")
return
}
if (*slice)[midin] > findVal {
binaryFind(slice,leftin,midin - 1,findVal)
}
if (*slice)[midin] < findVal {
binaryFind(slice,midin + 1,rightin,findVal)
}
if (*slice)[midin] == findVal {
fmt.Println("找到了,下标为",midin)
}
}
func main() {
/*
- **重点,众多面试都考察二分查找**
- 二分查找的基本思想:首先数组一定要有序,这是进行二分查找的必要条件。
- 二分查找的原理:求有序数列 两个最值leftindex&rightindex之和/2 得到一个middle的下标,通过middle下标的值和查找值比较,得到下面两种结果扩展:
- **数组从小到大排列**
arr[middle] > findVal :递归查找结果范围变成 leftindex ~ middle - 1
arr[middle] < findVal: 递归查找结果范围变成 middle + 1 ~ rightindex
arr[middle] = findVal: 正好,一次性就找到了
leftindex == rightindex : 最后一次比较
leftindex > rightindex :找不到
- **数组从大到小排列**
arr[middle] > findVal :递归查找结果范围变成 middle + 1 ~ rightindex
arr[middle] < findVal: 递归查找结果范围变成 leftindex ~ middle - 1
arr[middle] = findVal: 正好,一次性就找到了
leftindex == rightindex : 最后一次比较
leftindex > rightindex :找不到
- 上述两种比较方式也就诠释了为何二分查找比顺序查找快很多,因为不断二分二分迅速完成查找。
*/
var arr = [...]int{2,3,4,6,8}
slice := arr[:]
binaryFind(&slice,0,4,2)
}