快速排序及查找前k个数据

  • 三数取中
  • 查找前k名数据,不需要排名
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func QuickSort(arr []int) {
	quickSort(arr, 0, len(arr)-1)
}

func quickSort(arr []int, l, r int) {
	stdIndex := partition2(arr, l, r)
	if stdIndex < 0 {
		return
	}
	quickSort(arr, l, stdIndex-1)
	quickSort(arr, stdIndex+1, r)
}

// 找出前k名值,不需要排序
func FindK(arr []int, k int) {
	findK(arr, 0, len(arr)-1, k-1)
}

func findK(arr []int, l, r, k int) {
	stdIndex := partition(arr, l, r)
	if stdIndex < 0 {
		return
	}
	if stdIndex == k {
		return
	} else if stdIndex > k { // 如果k小于分界点,则从左边开始找
		findK(arr, l, stdIndex-1, k)
	} else { // 否则从右边开始找
		findK(arr, stdIndex+1, r, k)
	}
}

func partition(arr []int, l, r int) int {
	if l >= r {
		return -1
	}
	ll, rr := l, r
	stdIsLeft := true // 基准值是否在左
	for ll < rr {
		if stdIsLeft { // 如果基准值在左,基准值为arr[ll]
			if arr[rr] > arr[ll] { // 比较右边,如果大于基准值,右边左移,如果小于基准值,交换,基准值变换为右
				rr--
			} else {
				arr[ll], arr[rr] = arr[rr], arr[ll]
				ll++
				stdIsLeft = false
			}
		} else {
			if arr[ll] < arr[rr] { // 如果基准值在右,基准值为arr[rr]
				ll++
			} else {
				arr[ll], arr[rr] = arr[rr], arr[ll]
				rr--
				stdIsLeft = true
			}
		}
	}
	if stdIsLeft {
		return ll
	} else {
		return rr
	}
}

// 采用左右指针移动
func partition2(arr []int, l, r int) int {
	if l >= r {
		return -1
	}
	mid(arr, l, r)
	ll, rr := l+1, r
	for ll <= rr {
		if arr[rr] > arr[l] {
			rr--
		} else {
			arr[ll], arr[rr] = arr[rr], arr[ll]
			ll++
		}
	}
	arr[l], arr[rr] = arr[rr], arr[l]
	return rr
}

// 三数取中法
func mid(arr []int, l, r int) {
	midIndex := (l + r) / 2
	if arr[midIndex] > arr[l] && arr[midIndex] < arr[r] || arr[midIndex] < arr[l] && arr[midIndex] > arr[r] {
		arr[midIndex], arr[l] = arr[l], arr[midIndex]
		return
	}
	if arr[r] > arr[l] && arr[r] < arr[midIndex] || arr[r] < arr[l] && arr[r] > arr[midIndex] {
		arr[r], arr[l] = arr[l], arr[r]
	}
}

func main() {
	rand.Seed(time.Now().UnixNano())
	num := 200
	arr := make([]int, num)
	copy_arr := make([]int, num)
	for i := 0; i < num; i++ {
		arr[i] = rand.Intn(1000000)
	}
	//arr = []int{5,4,3,2,1,6,7,9,166,43}
	copy(copy_arr, arr)
	//arr = []int{47,130}
	QuickSort(arr)
	fmt.Println(arr)
	nnn := 20
	fmt.Println(arr[:nnn])
	FindK(copy_arr, nnn)
	fmt.Println(copy_arr[:nnn])
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值