算法(快速排序)
快速排序
快速排序是一种高效的排序算法,它基于将数据列划分为更小的数组。比如将一个数组分割成两个更小的数据。然后重复对两个以上元素的数组进行排序,直到元素不可分割为止。动画演示
文章图片
image 逻辑描述
- 以数组最后一个元素作为分割基准(
pivot
)。 - 声明两个变量(
lo
,hi
),指向最左、右元素,但是不包括基准位置。 - 移动
lo
位置找到大于,pivot
的元素。 - 移动
hi
位置找到小于,pivot
的元素。 - 交换
lo
和hi
元素位置,并重复操作。 - 当
lo
>=hi
,退出本次操作,从新寻找基准值。
package mainimport (
"fmt"
)func main() {
//声明数组
numbers := []int{35, 33, 42, 10, 14, 19, 27, 44, 26, 31}
//numbers := utils.GetRandSlices(10)
fmt.Printf("%v \n", numbers)
//开始排序: 第一遍 左、右
QuickSort(0, len(numbers)-1, &numbers)
fmt.Printf("%v \n", numbers)
}func QuickSort(left, right int, numbers *[]int) {
if right-left <= 0 { //数据已经不能再被分割。
return
} else {
pivot := (*numbers)[right] //找到基准元素
partIndex := Partition(left, right, pivot, numbers) //执行定位迁移操作。获取到基准原始交叉点。
//-----------------------------------------------------
//此时的数据已经由交叉点分割成左右两份。分别对左右的元素执行如此操作。
QuickSort(left, partIndex-1, numbers)//小于基准(左边)的元素,执行快速排序
QuickSort(partIndex+1, right, numbers) //大于基准(右边)的元素,执行快速排序
}
}
func Partition(left, right, pivot int, numbers *[]int) int {
lo := left
hi := right - 1 //不包含基准元素位置
for {
// 移动 `lo` 位置找到大于,`pivot` 的元素。
for (*numbers)[lo] < pivot {
lo++
}
// 移动 `hi` 位置找到小于,`pivot` 的元素。
for hi > 0 && (*numbers)[hi] > pivot {
hi--
}
//当移动的点交叉,本次迁移完成。退出
if lo >= hi {
break
} else {
//交换两个元素位置。
fmt.Printf(" 交换 :%d,%d\n", (*numbers)[lo], (*numbers)[hi])
(*numbers)[lo], (*numbers)[hi] = (*numbers)[hi], (*numbers)[lo]
}
}
//当 `hi` 和 `lo` 交叉以后,数据已经通过 `pivot` 分割成左右两段。那么 `pivot` 就需要移动到交叉点的位置。
if lo != right {
fmt.Printf(" 交换 :%d,%d\n", (*numbers)[lo], (*numbers)[right])
(*numbers)[lo], (*numbers)[right] = (*numbers)[right], (*numbers)[lo]
}
//返回交叉点。
return lo
}
Python
# -*- coding: UTF-8 -*-numbers = [35, 33, 42, 10, 14, 19, 27, 44, 26, 31]
length = len(numbers)def quick_sort(left, right, nums):
if left >= right:
return
else:
pivot = nums[right]
pivot_index = partition(left, right, pivot, nums)
quick_sort(left, pivot_index - 1, nums)
quick_sort(pivot_index + 1, right, nums)def partition(left, right, pivot, nums):
lo = left
hi = right - 1# 不包含基准元素位置while True:
# 移动 `lo` 位置找到大于,`pivot` 的元素。
for i in range(lo, hi + 1):
lo = i
if nums[i] > pivot:
break
# 移动 `hi` 位置找到小于,`pivot` 的元素。
for j in range(hi, lo - 1, -1):
hi = j
if nums[j] < pivot:
break# 当移动的点交叉,本次迁移完成。退出
if lo >= hi:
break
else:
# 交换两个元素位置。
print("交换:", nums[lo], nums[hi], "\n")
nums[lo], nums[hi] = nums[hi], nums[lo]# 当 `hi` 和 `lo` 交叉以后,数据已经通过 `pivot` 分割成左右两段。那么 `pivot` 就需要移动到交叉点的位置。
if lo != right:
print("交换:", nums[lo], nums[right], "\n")
nums[lo], nums[right] = nums[right], nums[lo]return loprint("排序前:")
print(numbers)
quick_sort(0, length - 1, numbers)
print("排序后:", numbers)
【算法(快速排序)】微信搜索:小码侠
文章图片
长按二维码关注我们
推荐阅读
- 画解算法(1.|画解算法:1. 两数之和)
- Guava|Guava RateLimiter与限流算法
- 一个选择排序算法
- SG平滑轨迹算法的原理和实现
- 《算法》-图[有向图]
- 排序(归并排序)
- LeetCode算法题-11.|LeetCode算法题-11. 盛最多水的容器(Swift)
- 虚拟DOM-Diff算法详解
- 《数据结构与算法之美》——队列
- 【图解】9张图彻底搞懂堆排序