排序和查找

排序

排序介绍
排序是将一组数据,依指定的顺序进行排列的过程。
排序的分类:
1)内部排序:
将所需要处理的所有数据都加载到内部存储器中进行排序。包括:交换式排序法、选择式排序法和插入式排序法
2)外部排序:
数据量过大时,无法全部加载到内存中,需要借助外部存储器进行排序。有:合并排序法直接合并排序法

交换式排序法
运用数据比较后,以判断规则对数据位置进行交换,以达到排序的目的。
交换式排序法又可分为:
1)冒泡排序法(Bubble sort)
2)快速排序法(Quick sort)

冒泡排序:
1)通过对待排序序列从后向前(从下标较大的元素开始),一次比较相邻元素的排序码,若发现逆序则交换,是排序码较小的元素从后部向前部(从下标较大的单元移向下标较小的单元),就像水底的下的气泡一样逐渐向上冒。
2)排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,说明序列有序,因此要在排序过程中设置一个标识flag判断元素是否进行过交换。从而减少不必要的比较。(优化)

//冒泡法:分为轮次和每轮的交换次数,两者的关系为 第几轮+该轮交换次数 = 数组长度
//从后往前
func bubbleSort(slice []int) {
	for i := 1; i < len(slice); i++ { //总轮数= 数组长度-1
		temp := 0
		flag := 0
		for j := len(slice) - 1; j >= i; j-- { //表示第i论时的j次交换 i + j = 5
			if slice[j] < slice[j-1] {
				temp = slice[j]
				slice[j] = slice[j-1]
				slice[j-1] = temp
				flag++
			}
		}
		if flag == 0 {
			switch i {
			case 1:
				fmt.Println("本身有序")
			default:
				fmt.Printf("第%v轮完成排序\n", i-1)

			}
			break
		}
	}
	fmt.Println("排序后:", slice)
}

//从前往后
func bubbleSort1(slice []int) {
	for i := 1; i < len(slice); i++ { //总轮数= 数组长度-1
		temp := 0
		flag := 0
		for j := 0; j < len(slice)-i; j++ { //表示第i论时的j次交换 i + j = 5
			if slice[j] > slice[j+1] {
				temp = slice[j]
				slice[j] = slice[j+1]
				slice[j+1] = temp
				flag++
			}
		}
		if flag == 0 {
			switch i {
			case 1:
				fmt.Println("本身有序")
			default:
				fmt.Printf("第%v轮完成排序\n", i-1)

			}
			break
		}
	}
	fmt.Println("从前向后~排序后:", slice)

}

func main() {
	intArr := [5]int{1, 15, 29, 8, 16}
	slice := intArr[:]
	fmt.Println("slice排序前:", slice) //slice排序前: [1 15 29 8 16]

	bubbleSort(slice) //排序后: [1 8 15 16 29]
	fmt.Println("-------------")
	bubbleSort1(slice) //本身有序   从前向后~排序后: [1 8 15 16 29]

	fmt.Println("intArr排序后:", intArr) //intArr排序后: [1 8 15 16 29]

}

Output
slice排序前: [1 15 29 8 16]
第2轮完成排序
排序后: [1 8 15 16 29]
本身有序
从前向后~排序后: [1 8 15 16 29]
intArr排序后: [1 8 15 16 29]

查找

在Golang中,常用的查找有两种:
1)顺序查找
2)二分查找(前提条件:该数组是有序的)

顺序查找
案例:

//顺序查找
	var name string
	fmt.Println("请输入查找的名字:")
	fmt.Scanln(&name)
	strArr := [5]string{"IronMan", "Spyder", "Doctor", "Hoke"}
	index := -1
	for i := 0; i < len(strArr); i++ {
		if name == strArr[i] {
			index = i
			break
		}
	}
	if index != -1 {
		fmt.Printf("找到%v,下标为%d\n", strArr[index], index)
	} else {
		fmt.Println("没有找到,", name)
	}

请输入查找的名字:
Spyder
找到Spyder,下标为1

二分查找
基本思路:
1.有序从小到大的数组arr,要查找的数是dstVal
2.先找到中间下标middle=(leftIndex+rightIndex)/2对应的值,与dstVal进行比较,存在三种情况:
2.1 如果arr[middel]> dstVal,就该在leftIndex---middle-1下标范围内寻找是否有元素值等于desVal
2.2如果arr[middel]< dstVal,就该在middle+1---rightIndex下标范围内寻找是否有元素值等于desVal
2.3恰好arr[middle]==dstVal,找到
3.退出递归的条件:由于leftIndex在递归中往右移动,增大;reightIndex在递归中往左移动,减小;故当rightIndex<leftIndex成立时,退出递归。

package main

import (
	"fmt"
)

func binaryFind(ptrArr *[5]int, leftIndex int, rightIndex int, dstVal int) {
	if rightIndex < leftIndex {
		fmt.Println("没找到")
		return //跳出程序 沒有此处会无限报“没找到”
	}
	middle := (leftIndex + rightIndex) / 2

	if (*ptrArr)[middle] > dstVal {
		binaryFind(ptrArr, leftIndex, middle-1, dstVal)
	} else if (*ptrArr)[middle] < dstVal {
		binaryFind(ptrArr, middle+1, rightIndex, dstVal)
	} else {
		fmt.Printf("找到%v,下标为%v\n", dstVal, middle)
	}
}

func main() {
	/*
	arr := [5]int{1, 5, 52, 152, 188}
	binaryFind(&arr, 0, len(arr)-1, 188)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值