快速排序
时间复杂度:O(logn)
算法步骤:
将数据根据一个值按照大小分为左右两边,左面小于此值,右面大于此值
将两边数据调用步骤1
将所有数据合并
优化:
标准的快速排序每次都取:数据的第一个元素作为基准来分左右两边。如果数据已经排好序了,那么快速排序的时间复杂度会上升到 O(n^2),所以会采用随机数来作为基准。
写法1:该写法消耗的空间较大
func QuickSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
splitdata := arr[0] //第一个数据
low := make([]int, 0) //比我小的数据
hight := make([]int, 0) //比我大的数据
mid := make([]int, 0) //与我一样大的数据
mid = append(mid, splitdata) //加入一个
for i := 1; i < len(arr); i++ {
if arr[i] < splitdata {
low = append(low, arr[i])
} else if arr[i] > splitdata {
hight = append(hight, arr[i])
} else {
mid = append(mid, arr[i])
}
}
low, hight = QuickSort(low), QuickSort(hight)
myarr := append(append(low, mid...), hight...)
return myarr
}
写法2:该写法消耗的空间较小
func QuickSort3(arr []int) {
_quickSort(arr, 0, len(arr)-1)
}
func _quickSort(arr []int, left int, right int) {
if left < right {
// 位置划分
middleIndex := partition(arr, left, right)
// 左面排序
_quickSort(arr, left, middleIndex-1)
// 右面排序
_quickSort(arr, middleIndex+1, right)
}
}
// 标准分割函数(分区)
func partition(arr []int, left int, right int) int {
pivot := arr[left] // 导致 left 位置为空
for left < right {
// right 指针值 >= pivot,right 指针左移
for left < right && arr[right] >= pivot {
right--
}
// 填补 left 位置的值, arr[left] 是一个空位置
arr[left] = arr[right]
// left 指针值 <= pivot left 指针右移
for left < right && arr[left] <= pivot {
left++
}
// 填补 right 位置的值, arr[right] 是一个空位置
arr[right] = arr[left]
}
// left = right
arr[left] = pivot
return left
}
写法3:使用 sort
package sort
import (
"sort"
)
func quickSort1(arr []int) {
sort.Slice(arr, func(i, j int) bool {
return arr[i] < arr[j]
}
}
// -------------------------------------------------------
type myInts []int
func (m myInts) Less(i, j int) bool { return m[i] < m[j] }
func (m myInts) Len() int { return len([]int(m)) }
func (m myInts) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func quickSort2(arr []int) []int {
sort.Sort(myInts(arr))
return arr
}
// [1,2,3,4,5,6,7]
标签:arr,right,int,func,排序,快速,left
From: https://www.cnblogs.com/geraldkohn/p/16996659.html