1.单路快速排序、2.双路快速排序、3.三路快速排序

1.单路快速排序

要点

将数字小于某个标定值得归入左边

递归

每次确定标点值的位置,然后递归的确定左右数组的标定值的位置。

代码片段
package algorithms

func QuickSortOneWay(arr []int) {
	n := len(arr)
	quickSortOneWay(arr, 0, n-1)
}

func quickSortOneWay(arr []int, l, r int) {
	if l >= r {
		return
	}
	pos := _quickSortOneWay(arr, l, r)
	quickSortOneWay(arr, l, pos-1)
	quickSortOneWay(arr, pos+1, r)
}

func _quickSortOneWay(arr []int, l, r int) int {
	flag := arr[l] //取某个一个值当做标定值,也就是想知道这个值应该在哪里
	j := l
	for k := j + 1; k <= r; k++ {
		if flag > arr[k] {
			j++
			arr[j], arr[k] = arr[k], arr[j]
		}
	}
	arr[j], arr[l] = arr[l], arr[j]
	return j
}
代码解释

主要逻辑在_quickSortOneWay这个函数,flag这个值其实可以用一个随机化取值得办法进行优化。

思路是随机取一个数与第一个元素交换,其余操作一样。

这个函数的遍历过程有两个快慢指针 j,k。其中k在前面探路,而j在后面记录当前小于标定值得位置。
每次找到一个小于标定值的数的时候,此时j向前移动且这个值与k交换。

如果不好理解,那么把它想象成贪吃蛇 ,每次在吃东西啊的时候头先过去,然后整个身体变长了。


2.双路快速排序

要点

从两边找到两个不符合分布的数值进行交换

递归

代码片段
func QuickSortTwoWay(arr []int) {
	n := len(arr)
	quickSortTwoWay(arr, 0, n-1)
}

func quickSortTwoWay(arr []int, l, r int) {
	if l >= r {
		return
	}
	pos := _quickSortTwoWay(arr, l, r)
	quickSortTwoWay(arr, l, pos-1)
	quickSortTwoWay(arr, pos+1, r)
}

func _quickSortTwoWay(arr []int, l, r int) int {
	flag := arr[l]
	i := l + 1
	j := r
	for {
		for ; i <= r && flag > arr[i]; {//找到一个比标定值大的位置
			i++
		}
		for ; j >= l+1 && flag < arr[j]; {//找到一个比标定值小的位置
			j--
		}
		if i > j {
			break
		}
		//如果i跟j分别在左右两边则交换
		arr[i], arr[j] = arr[j], arr[i]
		i++
		j--
	}
	arr[j], arr[l] = arr[l], arr[j]
	return j
}
代码解释

与单路排序不同的点在于这里是从左右两边开始。内部的两个循环的区间这里设置比较大,但是会提早结束所以不需要担心遍历次数多。


3.三路快速排序

要点

将数组分成3组 <标定值 =标定值 >标定值

递归

代码片段
func QuickSortThreeWay(arr []int) {
	n := len(arr)
	quickSortThreeWay(arr, 0, n-1)
}

func quickSortThreeWay(arr []int, l, r int) {
	if l >= r {
		return
	}
	left, right := _quickSortThreeWay(arr, l, r)
	quickSortThreeWay(arr, l, left-1)
	quickSortThreeWay(arr, right, r)
}

func _quickSortThreeWay(arr []int, l, r int) (left, right int) {
	flag := arr[l]
	left = l
	right = r + 1
	i := l + 1

	for i < right {
		if flag > arr[i] {
			arr[left+1], arr[i] = arr[i], arr[left+1]
			left++
			i++
		} else if flag < arr[i] {
			right--
			arr[i], arr[right] = arr[right], arr[i]
		} else {
			i++
		}
	}

	arr[l], arr[left] = arr[left], arr[l]
	return
}
代码解释

将小于标定值的放在左边,大于的放右边,等于的继续往前遍历


😁😁😁制作动画过程不易,请大家顺手点赞收藏咯 谢谢~😁😁😁
有其它题目不理解的也可以一起学习,如有错误欢迎指出~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值