基础算法二:快速排序

快速排序也是面试中经常问到的算法,人人都应该掌握。快速排序是对冒泡排序的改进,它的基本思想是:采用分而治之的思想,选取一个基准,一趟排序后把数据分成两部分,一部分都比基准小,另一部分都比基准点大,然后再对这两部分分别进行上述的操作,直到整个序列有序。快速排序因为数据的交换是跳跃的,所以速度比只和相邻数据交换的冒泡排序要快,平均时间复杂度为O(NlogN)。

该算法主要有两种实现方法:递归和非递归。

1.递归的实现方法:

def quick_sort(array):
    if len(array) < 2:
        return array
    basevalue = array[0]
    less = []
    great = []
    equal = [basevalue]
    for i in array[1:]:
        if i < basevalue:
            less.append(i)
        elif i > basevalue:
            great.append(i)
        else:
            equal.append(i)
    return quick_sort(less) + equal + quick_sort(great)


if __name__ == '__main__':
    array = [5, 8, 7, 6, 5, 4, 0, 3, 2, 1, 9]
    sorted = quick_sort(array)
    print(sorted)

结果为:
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]

2.非递归的实现利用了栈来完成,使用栈来记录每次分治数据的边界,将待处理数据的右边界索引、左边边界索引入栈,判断栈是否为空,如果不为空,取出两个栈元素,处理该两个栈元素范围内的数据:数据进行分区,使左边分区都小于等于基准值,右边分区都大于等于基准值,返回基准值的索引index。判断index-1>左边界索引,将index和左边界索引入栈。判断index+1<右边界索引,将右边界索引和index入栈。然后重复这个过程,代码如下:

def quick_sort_stack(arr):
    '''''
    模拟栈操作实现非递归的快速排序
    '''
    if len(arr) < 2:
        return arr
    stack = []
    stack.append(len(arr) - 1)
    stack.append(0)
    while stack:
        l = stack.pop()
        r = stack.pop()
        index = partition(arr, l, r)
        if l < index - 1:
            stack.append(index - 1)
            stack.append(l)
        if r > index + 1:
            stack.append(r)
            stack.append(index + 1)


def partition(arr, start, end):
    # 分区操作,返回基准线下标
    pivot = arr[start]
    while start < end:
        while start < end and arr[end] >= pivot:
            end -= 1
        arr[start] = arr[end]
        while start < end and arr[start] <= pivot:
            start += 1
        arr[end] = arr[start]
    arr[start] = pivot
    return start


if __name__ == '__main__':
    array = [5, 8, 7, 6, 5, 4, 0, 3, 2, 1, 9]
    quick_sort_stack(array)
    print(array)


结果为:
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值