快速排序的介绍
快速排序(QuickSort)是一种常用的、高效的排序算法,属于分治法的一种。它的基本思想是选择一个基准元素,将序列分为两部分,小于基准元素的部分和大于基准元素的部分,然后对这两部分分别递归地进行快速排序。
步骤:
-
选择基准元素: 从待排序的数组中选择一个元素作为基准元素。通常可以选择数组的第一个元素、最后一个元素或者随机选择。
-
划分操作: 将数组中小于基准元素的元素放在左侧,大于基准元素的元素放在右侧,相等的元素可以放在任意一侧。这个过程称为划分(Partition)。
-
递归排序: 对左右两个部分分别递归地进行快速排序。
-
合并: 递归的基本情况是数组长度为 0 或 1,此时已经有序。递归的结果是左侧部分有序、右侧部分有序,通过合并左右两个有序部分,整个数组变得有序。
平均时间复杂度:
快速排序的平均时间复杂度为 O(n log n),其中 n 是待排序数组的长度。它的性能通常优于其他简单的排序算法,尤其在大规模数据集上。然而,在最坏情况下(例如,选择的基准元素总是最大或最小元素),快速排序的时间复杂度可能达到 O(n^2)。为了避免最坏情况,通常采用随机选择基准元素或者使用三数中值法来提高算法的性能。
代码实现1:
以下代码是用递归实现的,
package main
import "fmt"
func quickSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
pivot := arr[0]
var left, right []int
for _, num := range arr[1:] {
//小于或等于pivot的就放进left切片,否则就放进right切片
if num <= pivot {
left = append(left, num)
} else {
right = append(right, num)
}
}
// 递归调用快速排序,利用append()函数拼接起来
return append(append(quickSort(left), pivot), quickSort(right)...)
}
func main() {
data := []int{8, 3, 1, 7, 0, 10, 2, 5}
sortedData := quickSort(data)
fmt.Println("排序前:", data)
fmt.Println("排序后:", sortedData)
}
代码实现2:
package main
import "fmt"
func quickSort(arr []int) {
if len(arr) <= 1 {
return
}
// 选择最后一个元素作为基准
pivot := arr[len(arr)-1]
low, high := 0, len(arr)-2
for low <= high {
// 从左向右找到第一个大于基准的元素
for low <= high && arr[low] <= pivot {
low++
}
// 从右向左找到第一个小于基准的元素
for low <= high && arr[high] > pivot {
high--
}
// 交换找到的元素
if low < high {
arr[low], arr[high] = arr[high], arr[low]
}
}
// 将基准元素放到正确的位置
arr[low], arr[len(arr)-1] = arr[len(arr)-1], arr[low]
// 递归排序左右两侧
if low > 0 {
quickSort(arr[:low])
}
if low+1 < len(arr) {
quickSort(arr[low+1:])
}
}
func main() {
data := []int{4, 11, 8, 0, 3}
fmt.Println("排序前:", data)
quickSort(data)
fmt.Println("排序后:", data)
}
结论:
中心思想也是把小于基准的数放在左边,大于基准的数放在右边,然后找到基准位置,在递归函数,基准为分割,分成两个切片,然后就递归函数