Python 实现快速排序

快速排序采用了一种分治策略,它的基本思想是:

  1. 先从数组中选取一个数作为基准数。
  2. 对数组进行分区,将比基准数大的数放在它的右边,小的放在左边。
  3. 对左右区间重复执行第二步,直到只有一个数为止。

对数组进行分区,有三种方法:

  1. 暴力执行,遍历数组,将比基准数小的和大的分别都放进一个新的数组,再将数组与基准数进行拼接。
  2. 挖坑填数法。
  3. 交换顺序法。

暴力法

这个方法很简单,代码先不写了。

挖坑填数法

找出基准数,在这里需要将比基准数小的放在基准数左边,把基准数大的放在基准数右边,所以需要两个变量 i 和 j 分别找到这两个类型的数,再进行操作。

数组array:

01234567
213215429182750

基准数 temp = 21,把 array[0] 放在了 temp 中,可以理解为在 array[0] 处挖个坑,然后再将其他数据填进来;

变量 j = 7 负责从右到左遍历寻找比基准数小的数;

变量 i = 0 负责从左到右遍历寻找比基准数大的数;

从上面的数组可以看出,必须先将基准数与比它小的数交换位置,所以应该先从右开始遍历;

当 j = 5 的时候,array[5] 小于 temp,符合条件,所以将它挖出来填进array[0],即array[0] = array[5],i++; 

01234567
183215429182750

然后形成了一个新的坑 array[5],所以就需要找一个新的数来填坑,移动 i ,这时候用 i 从左往右遍历寻找大于基准数的数填到 array[5] 中,当 i = 1的时候,array[1] = 32,大于temp,所以执行 array[5] = array[1],j--,此时 j = 4; 

01234567
183215429322750

移动 j ,以此类推,将 array[4] 填入 array[1] 的坑,array[1] = array[4],i++,此时 i = 2;

01234567
18915429322750

移动 i ,当 i = 3 的时候,array[3]大于temp,所以将它填入array[4]的坑,j--,i = 3;

01234567
189154242322750

 此时i = j = 3,则遍历结束,而 array[3] 是挖了还没填的坑,因此将 temp 填进去;

01234567
189152142322750

从而左边都是小于基准数的数,右边都大于基准数。最后采用分治策略,分别对左右两边的执行相同的操作。

代码如下:

def quick_sort(a, left, right):
    if(left >= right):
        return

    i = left
    j = right
    temp = a[left]

    while(i != j):
        while(a[j] > temp and i < j):
            j -= 1
        if(i < j):
            a[i] = a[j]
            i += 1
        while(a[i] < temp and i < j):
            i += 1
        if(i < j):
            a[j] = a[i]
            j -= 1

    a[i] = temp
    quick_sort(a, left, i-1)
    quick_sort(a, i+1, right)

    return a

#调用快速排序
list = [3, 2, 4, 6, 5, 1, 7]
sorted = quick_sort(list, 0, 6)
print(sorted)

交换顺序法

01234567
213215429182750

交换顺序法同样是设置变量 i 和 j ,分别从左和右开始遍历。

j 先移动;

j 从右遍历寻找小于基准数的值,找到后也停下来, j = 5;

i 从左遍历寻找大于基准数的值,找到后就停下来, i = 1;

交换数值。

01234567
211815429322750

继续遍历,i = 3, j = 4;

01234567
211815942322750

j 继续移动,j--, 此时 j = i = 3, 停止遍历;

将 array[3] 和 temp 交换位置;

01234567
918152142322750

关于为什么从右边开始遍历:

假如从左边开始遍历,进行最后一次交换之后,左边先开始往右移动,在上面倒数第二个表格中即 i = 4,此时的 i = j = 3,将array[4] 与temp交换的话,就无法实现正确的划分了。假如从右边开始遍历,会在 i = j 的时候指向比 temp 小的值,这时候将temp 与指向的数值进行交换,便能实现正确的划分。

代码如下:

def quick_sort1(a, low, high):
    if(low >= high):
        return

    i = low
    j = high
    temp = a[low]

    while(i != j):
        while(i < j and a[j] >= temp):
            j -= 1
        while(i < j and a[i] <= temp):
            i += 1
        if(i < j):
            t = a[i]
            a[i] = a[j]
            a[j] = t

    a[low] = a[i]
    a[i] = temp

    quick_sort1(a, low, i-1)
    quick_sort1(a, i+1, high)

    return a

#调用快速排序
list = [3, 2, 4, 6, 5, 1, 7]
sorted = quick_sort1(list, 0, 6)
print(sorted)

参考链接:

https://blog.csdn.net/MoreWindows/article/details/6684558

http://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值