排序 是将一组数据,依指定的顺序进行排列的过程

 常见排序方法

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