快排

快排介绍:
快排简单而言就是在数组中选取一个基准值。将小于基准值的放左边(或者放右边),大于基准值的放右边(或者放左边),分成两个数组。
再对得到的左右两个数组分别重复上述操作。这样若干轮下来我们会得到只有1个或0个元素的数组这种最基本情况。那不用排序直接返回即可。

举个例子:
【5,8,12,4,7,2,7】
我们计算的方法是这样的
1.选取基准值(可以按照一定的规则选取,或者随机选取,我们就直接选取第一个元素【5】吧)
2.切分得到两个数组(基准值单独提出来,我们就当不算数组)【4,2】(5)【8,12,7,7】
3.对左边数组重复1,2步骤得到【2】(4)【】
4,再对3得到的左边元素重复1,2步骤。因为3得到的两个数组只有1或0个元素,所以不用排序直接返回。得到【2,4】从而小于【5】的部分就排序完成了。退栈到第二步,执行右边的排序操作。同理就可以把大于5的部分也排序完成。

具体生成应该如下:
【5,8,12,4,7,2,7】
【4,2】(5)【8,12,7,7】
【2】(4)【】(5)【8,12,7,7】
【2】(4)【】(5)【7,7】(8)【12】
【2】(4)【】(5)【7】(7)【】(8)【12】

本质上快排是一种大事化小的分治思想。需要用到递归的方法。我认为这里有两种数组类型的快排。动态数组(非原地快排),以及非动态数组(原地快排)

一.动态数组快排
如果不需要原地排序,用动态数组排序其实比较好理解代码如下(python):

def quick_sort(self,num):
	#left,right分别保存小于基准值和大于基准值的元素
    left = []
    right = []
    #如果数组元素为0或1个,不用排序直接返回
    if len(num) <= 1:
        return num
    #此处选取了第一个元素作为基准值,也可选随机下标
    base = num[0]`
    for n in num[1:]:
        if n > base:
            left.append(n)
        else:
            right.append(n)
    return self.quick_sort(left) + [base] + self.quick_sort(right)

二.非动态数组快排(原地快排)

原地快排比上面的难理解一点。先上代码

class Solution(object):
	#快排函数
    def quick_sort(self,num,l,r):
    	#若排序的数组左边大于等于右边,说明只有一个或0个元素,自然不用处理
        if l < r:
            q = self.partition(num,l,r)
            self.quick_sort(num,l,q-1)
            self.quick_sort(num,q+1,r)
            
	#函数名写为分区,实际上,排序在这里实现,上面函数只是实现了递归。这里实现了排序
    def partition(self,num,l,r):
        #这个index指向最后一个大于(或小于,取决于你排序的顺序)基准值的元素的前一个元素。一开始我们就假设没有,故等于r
        index = r
        #从右往左遍历,大于基准值的元素往右抛,index--
        for i in range(r,l,-1):
           if num[i] > num[l]:
            	#选取了最左边的元素为基准值。
                num[i],num[index] = num[index],num[i]
                index -= 1
         #最后再把基准值移到当前index位置
        num[index],num[l] = num[l],num[index]
        return index

我简单再走一遍逻辑。还是【5,8,12,4,7,2,7】
实现逻辑如下

基准值为5,l = 0,r = 6,index = 6,从右往左遍历,大于基准值的往右抛
7 > 5,故7往右抛(和num[index]对调),index = 5
此时数组为【5,8,12,4,7,2,7】
2 < 5 不处理
此时数组为【5,8,12,4,7,2,7】
7 > 5 往右抛,num[5]和num[4]对调,index=4
此时数组为【5,8,12,4,2,7,7】
4<5不处理
12>5 往右抛.num[2]和num[[4]对调 index = 3
此时数组为【5,8,2,4,12,7,7】
8>5 往右抛num[1]和num[3]对调 index = 2
此时数组为【5,4,2,8,12,7,7】
遍历结束,将基准值移到index处 即num[l]和num[index]对调,此时数组为
【2,4,5,8,12,7,7】返回此时index值2.我们发现,下标大于2处所有元素大于基准值5,小于2处均小于等于基准值5.故一轮排序结束。再递归处理2左右的两个数组即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值