【面试总结】快速排序

快速排序

一把辛酸泪,在面试某翻译软件公司的时候。

面试官:同学啊,知道快排吗?
我:嗯嗯
面试官:你能口诉一下快排原理吗
我:额,这个,那个,巴拉巴拉一堆(奈何语言表达能力比较差,后面详细描述)
面试官:你这也不行啊,太拉跨了吧,你直接说一趟快排结果是什么吧
我:一趟快排的结果就是选定的基准元素呆在它应该待的位置,并且在这个数组中它前面的数比它小,它后面的数比它不小(大于等于)
面试官:有道理,那你写一下吧

于是乎我掏出我的键盘,写下了下面的代码

def quickSort(a,left,right):
    if right - left < 1:
        return a
    else:
        pre = a[left]
        l = left
        r = right
        while l < r:
            while l < r and a[r] >= pre:
                r -= 1
            a[l] = a[r]

            while l < r and a[l] <= pre:
                l += 1
            a[r] = a[l]
        a[l] = pre

        a = quickSort(a,left,l - 1)
        a = quickSort(a,l + 1,right)

        return a

跑了一下,没问题,以为稳了呀,这不搞定了吗?
结果面试官:你这写的什么玩意,能不能别写递归,给咱表演个循环版本

当时心里一紧,确实不会写循环版本的,咋整,赶紧下来学吧。

快排

快速排序,是先通过划分(partition)算法,将数组两分,划分的过程中,比主元(pivot)小的数字全部被划分到了左侧,比主元大的数字全部被划分到了右侧。然后对两分的数组进行递归。当数组两侧的长度均小于等于1,那么数组就自然有序了。

快速排序非递归的执行过程中,只需要一个堆栈空间,其运行过程如下:

1. 对原数组进行一次划分,分别将左边的索引、主元固定的位置和右边的索引入栈。
2. 判断 stack 是否为空,若是;直接结束;若不是,出栈,进行一次划分。
3. 通过左边索引、主元固定的位置,判断左边的长度大于 1,将左边进行2的划分并入栈;同理,进行右边操作。
4. 循环步骤 2、3。

代码

def quickOne(a,left,right):
    if left > right:
        return a,[right,right,right]
    pre = a[left]
    l = left
    r = right
    while l < r:
        while l < r and a[r] >= pre:
            r -= 1
        a[l] = a[r]

        while l < r and a[l] <= pre:
            l += 1
        a[r] = a[l]
    a[l] = pre
    return a,[left,l,right]

def quickSort(a):
    pointers = []

    l = 0
    r = len(a) - 1
    a,poi = quickOne(a,l,r)
    pointers.append(poi)

    while len(pointers) > 0:
        poi = pointers[-1]
        pointers.pop()
        [l,mid,r] = poi
        a,poi = quickOne(a,l,mid - 1)
        if poi[2] - poi[0] > 1:
            pointers.append(poi)
        a,poi = quickOne(a,mid + 1,r)
        if poi[2] - poi[0] > 1:
            pointers.append(poi)
    return a

PS:好好写基础的算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值