1.方法
如果我们要对下标 p 到 r 的数据进行排序,首先从中选择任意一个数据(假设下标为 q )作为分区点(pivot),遍历p到r的数据,将小于pivot的放到左边( p 到 q-1 ),pivot放中间( q ),大于或等于pivot的放右边( q+1 到 r ),这样分区就完成了;
我们再使用相同的方法对下标为 p 到 q-1 和 q+1 到 r 的数据进行排序,直到待排区间大小变为1,此时数组中数据就是有序的了。
注:pivot一般选择p到r区间中最后一个元素
2.分区操作的函数如何实现呢?
2.1 法一
1.申请两个临时数组A、B;
2.遍历 p 到 r 的数据;
3.将小于pivot的元素复制到A,大于pivot的元素复制到B;
4.将A、pivot、B中的数据依次复制到原数组 p 到 r 。
缺点:占用额外的内存空间,不是原地排序算法(在原数据存储空间上完成排序操作)。
2.2 法二
1.使用指针 i 把区间 nums[ p , r - 1 ]分成两部分( nums[ r ] 为pivot);
2.nums[ p , i - 1 ]元素都小于pivot,称为已处理区间,nums[ i , r - 1 ]称为待处理区间;
3.每次从待处理区间取一个元素 nums[ j ] 与pivot相比较,如果小于pivot,就把它插入已处理区间尾部,即 i 处(注:插入操作需要搬移其他数据,非常耗时,所以采用交换数据方式更好,即让 nums[ i ] 和 nums[ j ] 进行交换);
4.交换 nums[ i ] 和 nums[ r ]。
2.2.1 图示
以上就是法二的一次分区操作。
3.代码
def partition(nums,p,r):
i = p
pivot = nums[r]
for j in range(p,r):
# 当前元素小于pivot
if nums[j] < pivot:
nums[i],nums[j] = nums[j],nums[i]
i = i+1
nums[i],nums[r] = nums[r],nums[i]
return i
# 快速排序函数
def quick_sort(nums,p,r):
if p < r:
# 分区
pivot = partition(nums,p,r)
quick_sort(nums, p, pivot-1)
quick_sort(nums, pivot+1, r)