快排笔记: 递归和非递归快排实现

快排笔记: 递归和非递归快排实现

快速排序和归并排序一样,也是基于分治思想,通过递归地调用快速排序实现数组的排序。

递归快排

快排的基本思路就是在待排序的数组A[1,…n]中选择一个数m(一般选择A[n]),通过和数组中其他数比较(通过移动数组元素将大于m的数放在m的后面)确定m在这个数组中的位置p,并得到两个子数组A[1,…p-1](小于等于m)和A[p+1,n](大于m)(注:子数组可以为空数组)。然后,递归地对两个子数组进行上述操作,最后当数组中所有的元素都确定在数组中的位置时,排序完成。
代码可以写成:

def quickSort(A,start,end):
        '''
        数组为空(end < start) 
        数组长度为1(end == start)
        表明数组已经是有序的了,就直接返回
        '''
        if start<end:
            # 找到m的位置pos,并且移动数组元素
            pos = findPos(A,start,end)
            # 递归地对两个子数组执行quickSort()
            quickSort(A,start,pos-1)
            quickSort(A,pos+1,end)

递归算法具体python代码:

def reQuickSort(nums,start = 0,end = -1):
    if end == -1:
        end = len(nums)-1

    #递归结束判断
    if start >= end:
        return 

    #找到nums[end]的应在的位置,并且移动数组
    i = start
    j = end
    while i<j:
        if nums[i]>nums[j]:
            nums[i],nums[j-1],nums[j] = nums[j-1],nums[j],nums[i]
            j-=1
        else:
            i+=1

    #递归调用quickSort()
    reQuickSort(nums,start,i-1)
    reQuickSort(nums,i+1,end)

但是通过递归实现的快排在输入个数 n 较大时(如n>1000000)或者数组有序时,可能会出现栈溢出。这个通过非递归快排解决。

非递归快排

非递归的思路是:

  • 通过两个栈 startStack 和 endStack 来记录需要排序的子数组的起始下表start和终止下表end。
  • 初始化两个栈,向startStack中push 0,向endStack中push len(nums)-1.
  • while循环,终止条件为两个栈为空(排序完成)
  • 在循环中从两个栈中pop出这次循环的start和end, 如果start>=end continue循环, 否则完成findPos(A,start,end) 操作后得到两个待处理的子数组,将两个数组的start和end push进栈。

非递归算法具体python代码:

def quickSort(nums):
    #初始化两个栈
    startStack = [0,]
    endStack = [len(nums)-1,]

    #进入循环,两个栈均为空时,排序结束
    while startStack and endStack:
        #得到本次循环的start 和 end
        start = startStack.pop()
        end = endStack.pop()
        #判断子数组是否有序
        if start>end:
            continue
        i = start 
        j = end
        while i<j:
            if nums[i]>nums[j]:
                nums[i],nums[j-1],nums[j] = nums[j-1],nums[j],nums[i]
                j-=1
            else:
                i+=1
        #将两个子数组的开始和结尾push进栈中
        startStack.append(start)
        endStack.append(i-1)
        startStack.append(i+1)
        endStack.append(end)

结果

这里写图片描述
递归算法的性能要稍微比非递归算法性能好一点。
可以看到当递归算法在给随机的数组排序时,输入数组长度为10000000时也没有发生栈溢出,但是当输入数组有序的时候输入10000时就发生了栈溢出。这也是为什么在进行递归快排时经常要对数组random一下。

最后,新手第一次发博客,格式什么的都不太熟悉,整个逻辑可能也不太清楚,请见谅。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值