Go语言 大话数据结构——快速排序

知识内容参考《大话数据结构》P417

实例代码:

package main

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

func QSort(a []int, low int, high int) {

	if low < high {
		pivot := Partition2(a, low, high) //依据某一个临界值(左侧的小于此值,右侧的大于此值),
		QSort(a, low, pivot-1)            //对左侧递归排序
		QSort(a, pivot+1, high)           //对右侧递归排序
	}
}
//------------------------------------------------------------
//错误写法
func Partition(a []int, low int, high int) int {
	temp := a[low]
	for {
		if low >= high {
			break
		}
		if temp <= a[high] {
			high--
		} else {
			temp, a[high] = a[high], temp  //交换的并非比较的值,而是 数组内 大于 小于temp的值
		}
		if temp >= a[low] {
			low++
		} else {
			temp, a[low] = a[low], temp
		}
	}
	return low
}
//------------------------------------------------------------

//方法2
func Partition2(a []int, low int, high int) int {
	temp := a[low]  //取最左侧的值作为比较值(移位之后的数组,参考值会在中间位置: 小于值 参考值  大于值 )
	for {
		if low >= high {
			break
		}
		//取最左侧的值作为比较值,因此从右端开始
		for low<high&&temp <= a[high] {//必须有 low<high  否则 对于high来说,若以temp完成分割,会继续前移,出现越界
			high--
		}
		a[low], a[high] = a[high], a[low]

		for low<high&&temp >= a[low] {//必须有 low<high  否则 对于low来说,若以temp完成分割,会继续后移,出现越界
			low++
		}
		a[low], a[high] = a[high], a[low]
	}
	return low
}
//方法1
func Partition1(a []int, low int, high int) int {
	//取左侧的索引值为参考值,注意:数组在交换的同时参考值也会随之交换
	temp := low
	for {
		if low >= high {
			break
		}
		for low < high && a[temp] <= a[high] {
			high--
		}
		a[temp], a[high] = a[high], a[temp]
		temp = high //更新位置

		for low < high && a[temp] >= a[low] {
			low++
		}
		a[temp], a[low] = a[low], a[temp]
		temp = low //更新位置
	}
	return low
}

func main() {
	rand.Seed(time.Now().UnixNano())
	arr := make([]int, 0)
	for i := 0; i < 25; i++ {
		arr = append(arr, rand.Intn(1000))
	}
	fmt.Println("排序之前的切片为:")
	fmt.Println(arr)
	low := 0
	high := len(arr) - 1
	QSort(arr, low, high)
	fmt.Println("通过快速排序方法排序之后的切片为:")
	fmt.Println(arr)
}

另外一种思路:

package main

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

func quickSort(left, right int, arr []int) {
	l := left
	r := right
	value := arr[(l+r)/2]
	//进行一次排序
	for l < r {
		for arr[l] < value {
			l++
		}
		for arr[r] > value {
			r--
		}
		if l >= r {
			break
		}
		arr[l], arr[r] = arr[r], arr[l]
		if arr[l] == value {  //为了应对相同的数字
			r--
		}
		if arr[r] == value { //为了应对相同的数字
			l++
		}
	}
	//非常重要,如果不加,卡在 l=r处不会动了,形成死递归。
	if l == r {
		l++
		r--
	}
	//左递归
	if l < right {
		quickSort(l, right, arr)
	}
	//右递归
	if r > left {
		quickSort(left, r, arr)
	}
}
func main() {
	rand.Seed(time.Now().UnixNano())
	arr := make([]int, 0)
	for i := 0; i < 25; i++ {
		arr = append(arr, rand.Intn(1000))
	}
	fmt.Println("排序之前的切片为:")
	fmt.Println(arr)
	quickSort(0, len(arr)-1, arr)
	fmt.Println("排序之后的数据为:")
	fmt.Println(arr)
}

了解更多Go语言知识https://study.163.com/course/introduction/1210620804.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值