快速排序(单边、双边两种)

无论是单边快排还是双边快排都需要注意以下一些关键点:

1.快排核心在于递归。

2.每回都需要选择一个基准元素,将该基准元素放置正确位置,并且将比其小的元素统统移到该位置左边,比其大的元素移到该元素右边。

3.防置完毕后需要拿到基准元素的位置,再分别对左右两边调用该方法进行递归。

双边快排:

1.1.需要注意边界问题,两个指针移动时也要判断i<j。

1.2.需要注意最后ij重合的位置,需要考虑这个位置和基准元素的大小关系,因为都有可能。

package main

import "fmt"

// 双边快排
func quickSort(arr []int, left int, right int) {
	if left < right {
		pos := partition(arr, left, right)
		quickSort(arr, left, pos-1)
		quickSort(arr, pos+1, right)
	}
}

func partition(arr []int, left int, right int) int {
	i := left
	j := right
	pivot := arr[left]
	for i < j {
		for i < j && arr[i] <= pivot {
			i++
		}
		for i < j && arr[j] > pivot {
			j--
		}
		//i==j,或者真的需要交换,交换即可
		swap(arr, i, j)
	}
	pos := i
	if arr[pos] > pivot {
		pos--
		swap(arr, left, pos)
	} else {
		swap(arr, left, pos)
	}
	return pos
}

func swap(arr []int, i int, j int) {
	if i != j {
		temp := arr[i]
		arr[i] = arr[j]
		arr[j] = temp
	}
}

//func main() {
//	arr := make([]int, 5)
//	arr[0] = 2
//	arr[1] = 1
//	arr[2] = 4
//	arr[3] = 3
//	arr[4] = 5
//	fmt.Println(arr)
//	quickSort(arr, 0, len(arr)-1)
//	fmt.Println(arr)
//}

func main() {
	arr := make([]int, 8)
	arr[0] = 2
	arr[1] = 3
	arr[2] = 1
	arr[3] = 4
	arr[4] = 9
	arr[5] = 8
	arr[6] = 7
	arr[7] = 5
	fmt.Println(arr)
	quickSort(arr, 0, len(arr)-1)
	fmt.Println(arr)
}

单边快排:

2.1.需要额外注意,基准元素只能先选最后一个位置,因为在遍历过程中,第一个元素(位置较小的元素)有可能与其他比基准元素小的元素发生交换,最后想把基准元素放到应该的位置上时,却发现基准元素被换到未知地方去了

2.2.基准元素自身位置不需遍历 ,最后pointer指向的位置一定是大于基准元素的(如果有的话,否则是基准元素自身),因为比基准元素小的都移动到比pointer低的位置了,交换即可。没有的话pointer也会指向基准元素自身,交换与否无影响。

package main

import (
	"fmt"
)

// 单边快排
func quickSort(arr []int, low int, high int) {
	if low < high {
		pos := partition(arr, low, high)
		quickSort(arr, low, pos-1)
		quickSort(arr, pos+1, high)
	}
}

// 返回基准元素的position,并将基准元素放在正确位置
func partition(arr []int, low int, high int) int {
	//基准元素取最高,防止基准元素交换位置被交换的未知位置
	pivot := arr[high]
	pointer := low
	//<high,high不用遍历
	for i := low; i < high; i++ {
		if arr[i] <= pivot {
			//swap
			temp := arr[i]
			arr[i] = arr[pointer]
			arr[pointer] = temp
			//指针后移
			pointer++
		}
	}
	//基准元素一到正确位置上
	temp := arr[pointer]
	arr[pointer] = arr[high]
	arr[high] = temp
	return pointer
}

func main() {
	arr := make([]int, 5)
	arr[0] = 2
	arr[1] = 1
	arr[2] = 4
	arr[3] = 3
	arr[4] = 5
	fmt.Println(arr)
	quickSort(arr, 0, len(arr)-1)
	fmt.Println(arr)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值