package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
list := []int{123, 543, 6, 567, 34, 869797, 0, 5, 56, 245, 3, 832, 4, 756283, 34, 345, 64, 76, 235, 2, 7568, 278, 345, 534, 865, 34, 2, 24, 7, 8, 69, 6, 65, 3454, 2, 67, 5, 85, 34, 53, 75, 2345, 8, 5}
fmt.Println("原切片:", list)
//快排
quickSort(list, 0, len(list)-1)
fmt.Println("快排后:", list)
//洗牌
shuffle(list)
fmt.Println("洗牌后:", list)
//归并
temp := make([]int, len(list))
mergeSort(list, 0, len(list)-1, temp)
fmt.Println("归并后:", list)
//二分
fmt.Println("二分查找69:", binSearch(list, 69))
fmt.Println("二分查找1:", binSearch(list, 1))
fmt.Printf("target为%d的数在位置%d\n", 2, BrSearch(list, 2))
//洗牌
shuffle(list)
fmt.Println("洗牌后:", list)
//topk:一堆数求最大的几个,或者求最小的几个
fmt.Printf("求最大的第%d个数据:%d", 5, HeapSort(list, 5))
}
//快排算法
func quickSort(nums []int, left, right int) {
if left < right {
pos := portion(nums, left, right)
quickSort(nums, left, pos-1)
quickSort(nums, pos+1, right)
}
}
func portion(nums []int, left, right int) int {
sentry := nums[left]
for left < right {
for left < right && nums[right] >= sentry {
right--
}
nums[left] = nums[right]
for left < right && nums[left] <= sentry {
left++
}
nums[right] = nums[left]
}
nums[left] = sentry
return left
}
//洗牌算法
func shuffle(nums []int) {
rand.Seed(time.Now().UnixNano())
for i := len(nums) - 1; i > 0; i-- {
j := rand.Intn(i)
nums[i], nums[j] = nums[j], nums[i]
}
}
//归并排序算法
func mergeSort(nums []int, left, right int, temp []int) {
if left < right {
mid := (left + right) / 2
mergeSort(nums, left, mid, temp)
mergeSort(nums, mid+1, right, temp)
merge(nums, left, right, temp)
}
}
func merge(nums []int, left, right int, temp []int) {
mid := (left + right) / 2
Lpos, Rpos := left, mid+1
move := left
for Lpos <= mid && Rpos <= right {
if nums[Lpos] > nums[Rpos] {
temp[move] = nums[Rpos]
Rpos++
} else {
temp[move] = nums[Lpos]
Lpos++
}
move++
}
for Lpos <= mid && Rpos > right {
temp[move] = nums[Lpos]
Lpos++
move++
}
for Lpos > mid && Rpos <= right {
temp[move] = nums[Rpos]
Rpos++
move++
}
for left <= right {
nums[left] = temp[left]
left++
}
}
//二分查找
func binSearch(nums []int, k int) int {
left, right := 0, len(nums)-1
for left <= right {
mid := (left + right) / 2
if nums[mid] == k {
return mid
} else if nums[mid] > k {
right = mid - 1
} else if nums[mid] < k {
left = mid + 1
}
}
return -1
}
//寻找最右侧边界的位置
func BrSearch(nums []int, target int) int {
left, right := 0, len(nums)-1
mark := -1
for left <= right {
mid := (left + right) / 2
if nums[mid] == target {
mark = mid
for mark < len(nums)-1 && nums[mark] == nums[mark+1] {
mark++
}
break
} else if nums[mid] > target {
right = mid - 1
} else if nums[mid] < target {
left = mid + 1
}
}
return mark
}
//堆排序 topk 快排也能topk
func HeapSort(nums []int, k int) int {
size := len(nums)
for k > 0 && size > 1 {
buildHeap(nums, size)
nums[0], nums[size-1] = nums[size-1], nums[0]
size--
k--
if k == 0 {
return nums[size]
}
}
return -1
}
func buildHeap(nums []int, size int) {
parent := size/2 - 1
for parent >= 0 {
heapify(nums, parent, size)
parent--
}
}
func heapify(nums []int, parent, size int) { //大根堆
max := parent
lpos := parent*2 + 1
rpos := parent*2 + 2
if lpos < size && nums[lpos] > nums[max] {
max = lpos
}
if rpos < size && nums[rpos] > nums[max] {
max = rpos
}
if max != parent {
nums[max], nums[parent] = nums[parent], nums[max]
heapify(nums, max, size)
}
}
【Go语言】洗牌、快排、归并、二分、堆排序、topk算法集合
于 2022-09-12 10:24:22 首次发布