【Go语言】洗牌、快排、归并、二分、堆排序、topk算法集合

该博客主要介绍了Go语言中实现快速排序、洗牌算法、归并排序以及二分查找的详细过程。通过示例代码展示了如何对整数切片进行排序,并探讨了二分查找的实现及其应用。此外,还讨论了寻找目标值在有序数组中最右侧边界的方法。最后,展示了如何使用堆排序找到数组中的最大k个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辛集电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值