排序 是将一组数据,依指定的顺序进行排列的过程
常见排序方法
1. 内部排序
//指将需要处理的所有数据都加载到"内存"进行排序 适合数据量较小时使用
//包括"交换式排序法"、"选择式排序法"和"插入式排序法"
2. 外部排序法
//数据量过大,无法全部加载到内存重,需要借助外部存储进行排序
//包括"合并排序法"和"直接合并排序法"
一、交换式排序法
交换式排序法属于内部排序法,是运用数据的值进行比较后,根据规则对数据位置进行交换以达到排序的目的
冒泡排序
冒泡排序意思是,通过排序序列从后向前(从下标较大的元素到下标小的元素) 依次比较相邻的元素的大小
如果发现前面的值小于后面的值则交换,使较小的元素逐渐从后面移到前面
案例
package main
import "fmt"
func main() {
var varr [5]int = [5]int{24,69,80,57,13}
fmt.Println(varr)
for i := 0; i < len(varr) - 1; i++{
var temp int
if varr[i] > varr[i + 1] { //当前面的值大于后面的值时,双方位置互换
temp = varr[i + 1]
varr[i+1] = varr[i]
varr[i] = temp
}
}
fmt.Println(varr)
}
//循环对比值1和值2的大小,如果1比2大则互换
//第一轮24没69大 结果[24,69,80,57,13]
//第二轮69没80大 结果[24,69,80,57,13]
//第三轮80比57大 结果[24,69,57,80,13]
//第四轮80比13大 结果[24,69,57,13,80]
返回
[24 69 80 57 13] #原先的值
[24 69 57 13 80] #排序后的值
上面我们只是将没对值进行了一个对比置换,但如果想要将所有的进行对比,还要加点东西
package main
import "fmt"
func main() {
var varr [5]int = [5]int{24,69,80,57,13}
//上面已经实现了把最大值提取出来,我们只需要让这个操作重复几次即可
//下面我们设置了循环次数是数组的长度
//这样,当循环完第一次后,得到[24 69 57 13 80]
//第二次循环[24 57 13 69 80] 依次类推
for j := 1; j < len(varr);j++ {
for i := 0; i < len(varr)-1; i++ {
var temp int
if varr[i] > varr[i+1] {
temp = varr[i+1]
varr[i+1] = varr[i]
varr[i] = temp
}
}
}
fmt.Println(varr)
}
为了方便重复去调用这个功能,我们将他写成一个单独的函数
package main
import "fmt"
func bubblesort(varr *[5]int) { //前面我们学习了指针的概念,如果想要在一个函数中操作其他函数中的变量就需要指针
//指针数据只能接收内存地址,并且传入的值的类型必须一直
//这里使用 varr *[*]int 说明我们需要接收内存地址的对象必须也是一个int数组
temp := 0
for i :=0; i < len(*varr) - 1 ; i++{ //在函数中调用需要带上星号"*"
for j := 0; j < len(*varr) -1 -i; j++{
if (*varr)[j] > (*varr)[j + 1]{
temp = (*varr)[j]
(*varr)[j] = (*varr)[j + 1]
(*varr)[j + 1] =temp
}
}
}
}
func main() {
var varr [5]int = [5]int{24,69,80,57,13}
bubblesort(&varr) //通过& 将varr这个数组的内存地址传入到bubblesort函数中,使用指针接收
fmt.Println(varr)
}
其他排序方法参考文档
二、数组查询https://www.cnblogs.com/traditional/p/14624541.html
1、顺序查找
案例1 使用for循环查询
/*
思路
1. 定义一个数组 (白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王)
2. 从控制台接收一个名称,依次比较,如果发现有,则提示相应信息
*/
package main
import (
"fmt"
)
func main(){
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",heroName,i)
break
} else if i == len(names) -1 {
//这里的i 等于长度减一,说明到了最后一个元素了,就直接提示没有找到
fmt.Printf("没有找到%v",heroName)
}
}
}
返回
清输入要查找的人名...
金毛狮王
找到金毛狮王,下标1
案例2
package main
import (
"fmt"
)
func main(){
names := [4]string{"白眉鹰王","金毛狮王","紫衫龙王","青翼蝠王"}
var heroName = ""
fmt.Println("清输入要查找的人名...")
fmt.Scanln(&heroName)
//修改为如下
index := -1 //设置索引位的默认值为-1
for i :=0; i < len(names); i++ {
if heroName == names[i] {
//fmt.Printf("找到%v,下标%v",heroName,i)
index = i //当可以找到时,给index赋值索引位
break
}
}
if index != -1{ //当for结束后判断index是否不为-1,如果不为-1则有值输出即可,
fmt.Printf("找到%v 下标%v \n", heroName,index)
}else{
fmt.Printf("没有找到%v", heroName)
}
}
2、 二分查找
要求
请对一个有序数组进行二分查找 {1,8,10,89,1000,1234}
输入一个数看看该数组是否存在此数,并求出对应下标,如果没有则提示没有这个数(递归)
二分查找的思路
二分查找的前提, 他必须是一个有序的数组。总的来说,就是先找到数组最中间的值(middle)
然后拿着这个值去和你要查询的值(findvar)去对比,通常来说,对比会出现3种结果,如下
1、中间的值(middle) 比查询的值(findvar)大
当中间的值大于查询的值,那么他会从开头到中间的索引位再取一个中间值去对比,重复这个操作
2、中间的值(middle) 比查询的值(findvar)小
当中间的值小于查询的值,那么他会以中间到结尾的索引位再取一个中间值去对比,重复这个操作
3、中间的值(middle) 等于查询的值(findvar)
如果等于 那么就匹配到了
案例
package main
import(
"fmt"
)
func BinaryFind(arr *[6]int, leftIndex int, rightIndex int, findVal int){
if leftIndex > rightIndex{ //两边的索引是一直在向中间靠拢的,到最后找不到时,左面索引的值会比右边大
fmt.Println("找不到") //就说明没有该数据,程序终止
return
}
middle := (leftIndex + rightIndex) / 2 //将起始索引到终止索引相加得到剩余位置的最大值,然后除以2获取中间的索引
if (*arr)[middle] > findVal{
//当拿出的值大于你查询的值,说明你查询的值在当前索引的左面,右面索引都可以排除了
BinaryFind(arr, leftIndex, middle -1, findVal)
//再次查询,传入的最大值是值是从middle-1,表示下次查询的范围是0-中间值的范围
} else if (*arr)[middle] < findVal {
//第二种情况,拿到索引的值比你查询的要小,说明值在右边,同上
BinaryFind(arr, middle + 1, rightIndex, findVal)
} else { //第三种情况,等于,那么就不计算了之间输出
fmt.Printf("找到了,下标位%v\n",middle)
}
}
func main(){
arr := [6]int{1, 8, 10, 89, 1000, 1234}
findVal := 8 //要查询的值
BinaryFind(&arr, 0, len(arr) - 1, findVal) //在调用时传入数组、起始索引值、最大索引值、要查询的值
}
返回
找到了,下标位1