func BubbleSort(arr []int) {
// 最外层的循环表示循环几轮
for i := 0; i < len(arr); i++ {
// 内侧是循环几次,注意比较的时候索引越界
// 所以我们在比较的时候只需要走到数组长度的前一个
// 因为内侧比较的时候已经加1
// 所以倒数第二个也会倒数第一个数据作比较
for j := 0; j < len(arr)-1; j++ {
// 如果数组内的数据不满足条件就交换
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
func SelectSortData(arr []int) {
// 最外侧也是循环几轮
for i := 0; i < len(arr); i++ {
// 因为全部都要比较,选择数组的第一个下标为最小的数字
min := i
// 自己和自己比较没有意义,所以让前一个和后一个比较
for j := i + 1; j < len(arr); j++ {
if arr[min] > arr[j] {
min = j
}
}
// 如果一轮比较完了,最小的小标在循环内被修改过了
// 说明还不是最小的下标,
// 就要交换他俩索引上的数据
if min != i {
arr[min], arr[i] = arr[i], arr[min]
}
}
}
// 下边的思想是升序,数据从后往前移
// 每轮指移动一个数据
func InsertSort(arr []int) {
// 第一轮如果从0开始,满足不了第二个循环的条件,所以下标直接开始是1
for i := 1; i < len(arr); i++ {
backup := arr[i] // 开始先备份第二个数字
// 然后让备份的数据和前一个数据比较
j := i - 1
// 下标是有效的索引且要往前移动的数据必须小于前面的数据
for j >= 0 && backup < arr[j] {
// 让后面的数据复制为前面的数据
arr[j+1] = arr[j]
// 然后让数据继续往前走,
j--
}
// 如果数据不满足上边的循环条件,那就是前一个数据刚好是合适的位置
arr[j+1] = backup
}
}
// 快速排序法就是选择一个数据,
// 然后按照这个数据把这堆数据分为三类
// 比自己小、等于自己的、比自己大的,然后递归调用,最后把数据拼接到一起
// 但是递归调用数量大的时候避免击穿,可以改为伪递归,伪递归自行百度
func QuickSort(arr []int) []int {
// 既然要递归调用就要找好出口
// 数据长度再剩下1个或者小于一个的时候就开始返回
if len(arr) <= 1 {
return arr
}
capData := arr[0]
gt := []int{}
lt := []int{}
mid := []int{capData} //自己肯定等于自己,就不用从0开始比较了
for i := 1; i < len(arr); i++ {
if capData > arr[i] {
lt = append(lt, arr[i])
} else if capData < arr[i] {
gt = append(gt, arr[i])
} else {
mid = append(mid, arr[i])
}
}
// 递归调用,然后重组数据并返回新的数组
lt, gt = QuickSort(lt), QuickSort(gt)
sorted := append(append(lt, mid...), gt...)
return sorted
}