for i := 0; i < length; i++ { // 记录第一个数据 min := data[i] index := i
// 获取到最小的值以及对应的索引 for j := i + 1; j < length; j++ { if min > data[j] { min = data[j] index = j } } // 如果最小的值不是当前序列的第一个值 // 那么需要进行交换 if index != i { // 交换最小值 data[index], data[i] = data[i], min } } }
funcBubbleSort(nums []int) { flag := false n := len(nums) // 这里采用的是不断将最大的移动到数组的最后面 // 当然也可以将最小的移动到最前面来 for i := 0; i < n ; i ++{ for j := 0; j < n-1 -i; j ++{ if nums[j] > nums[j+1]{ nums[j], nums[j+1] = nums[j+1], nums[j] flag = true } } if !flag{ fmt.Println("一轮遍历中没有进行交换,说明数组已经有序") break } fmt.Println(nums) } }
funcmergeSort(nums []int, left, right int) { if left >= right { return } mid := (right-left)/2 + left mergeSort(nums, left, mid) mergeSort(nums, mid+1, right) merge(nums, left, mid, right) }
// 合并两个数组,分别是从 left -> mid , mid -> right 索引开始 funcmerge(nums []int, left, mid, right int) { // 辅助数据 tmp := make([]int, right-left+1)
for i := left; i <= right; i++ { tmp[i-left] = nums[i] } i, j := 0, mid-left+1 k := left for k <= right && i <= mid-left && j <= right-left { if tmp[i] > tmp[j] { nums[k] = tmp[j] k++ j++ } else { nums[k] = tmp[i] i++ k++ } } for i <= mid-left { nums[k] = tmp[i] i++ k++ }
funcsort(arr []int, left, right int) { if left >= right { return }
i := left j := right
// 选定一个分界点 // 如果直接下面这种方式取的话,如果数据是有序的,那么时间复杂度相比较会比较高 index := arr[i] // 也可以随机挑选一个 // rand.Seed(time.Now().UnixNano()) // var random int // random = rand.Int() % (right-left+1) + left // 将随机选中的移动到最左边 // arr[i], arr[random] = arr[random], arr[i] // 这里只是为了更新上面的index,如果直接写的话,可以去掉上的赋值,直接使用index:= arr[i] // index = arr[i]
for i < j { // 右边界不断向左移动,如果碰到比index小的数据 // 则需要将左边的i对应的数据赋值为对应的值 for i < j && arr[j] >= index { j-- } if i < j { arr[i] = arr[j] i++ } // 左边界不断往右移动,如果碰到比index小的数据 // 则将右边的这个数据赋值索引j对应的数据 for i < j && arr[i] <= index { i++ }
// 建大根堆 funcbuildHeap(nums []int) { size := len(nums) for i := size / 2; i >= 0; i-- { down(nums, i, size) } }
// 插入元素的时候需要使用 funcup(nums []int, i int) { for { // 父结点计算公式!! parent := (i - 1) / 2 // 如果父结点大于子节点了,说明不需要调换,已经满足条件了 // 如果 i == parent 说明 i = 0 了,没有父结点,也不需要调换 if i == parent || nums[parent] > nums[i] { break } // 父结点没有子节点i的值大,需要调换 nums[parent], nums[i] = nums[i], nums[parent] } }
// 初始化的时候需要建堆 // 删除元素的时候需要down: // 将第一个元素和最后一个元素进行调换, 然后重新 down(nums, 0, size) funcdown(nums []int, i int, size int) { left, right := 2*i+1, 2*i+2 j := i
// 找到最大的元素的下标 if left < size && nums[left] > nums[j] { j = left } if right < size && nums[right] > nums[j] { j = right }
if j != i { nums[i], nums[j] = nums[j], nums[i] down(nums, j, size) } }
// 不用递归也可以 funcdown2(nums []int, i, size int) { for { left, right := i*2+1, i*2+2 // 说明i是叶子节点 if left >= size { break } // 找到最大的节点 largest := i if left < size && nums[left] > nums[largest] { largest = left } if right < size && nums[right] > nums[largest] { largest = right }
if largest != i { nums[i], nums[largest] = nums[largest], nums[i] i = largest } else { // 如果最大的节点就是本身,那么后面也不需要进行操作了 break } } }
// 比如我们需要排序年龄,那么我们可以估算年龄在[0,200]中 funcCountingSort(nums []int) { count := make([]int, 200) for _, num := range nums { count[num] ++ } index := 0 for i :=0; i < len(count); i ++ { // 出现了多少次,排序后添加到原数组多少次 for j:= 0; j < count[i]; j++ { nums[index] = i index ++ } } }