快速排序的三种方法

今日复习了一些快速排序算法。

hoare法

快速排序由Hoare在1960年提出。它的基本思想是:通过排序将需要排序的数据分割成独立的两部分,左边的所有数据都比右边的小,然后再按此方法对这两部分数据分别进行快速排序递归,使其变成有序序列。

在实践过程中,等号的位置问题、递归返回以及指针的移动问题都值得思考。

我们以序列[1, 10, 99, 23, 43, 11, 2]为例。

  1. 就第一趟循环而言,选择最左侧的元素1key,与序列中元素进行比较。
  2. 因为以最左侧为key,所以右侧指针right首先移动。在这个例子中,此举是为了防止1右边的元素都比它大的情况。这样right就会移动到0的位置,即不需要交换位置。
  3. 每一次左右指针的移动都要判断left < right,以免交叉产生错误。

每一趟排序如下:

[1, 10, 99, 23, 43, 11, 2] 左指针: 0  右指针: 0
[1, 10, 2, 23, 43, 11, 99] 左指针: 2  右指针: 6
[1, 10, 2, 23, 43, 11, 99] 左指针: 2  右指针: 2
[1, 2, 10, 23, 11, 43, 99] 左指针: 4  右指针: 5
[1, 2, 10, 23, 11, 43, 99] 左指针: 4  右指针: 4
[1, 2, 10, 11, 23, 43, 99] 左指针: 5  右指针: 5
[1, 2, 10, 11, 23, 43, 99]

整体代码如下:

def quickSort(input,left,right):
    if left>= right:
        return
    min_index=left
    max_index=right
    key_value = input[left]
    while left < right:
        while input[right] >= key_value and left < right:
            right -= 1
        while input[left] <= key_value and left < right:
            left += 1
        input[left], input[right] = input[right], input[left]
    input[min_index],input[left]=input[left], input[min_index]
    quickSort(input,min_index,left-1)
    quickSort(input,left+1,max_index)

挖坑法

挖坑法在hoare的基础上进行了改进。主要是把左右指针的位置作为坑,将需要更改顺序的元素填入坑中。左侧的坑left填入原本在右边但是<key_value的元素input[right]。同理,右边的坑填原本在左边但是>key_value的元素。

整体代码如下:

def quickSort2(input, left, right):
    if left >= right:
        return
    min_index = left
    max_index = right
    key_value = input[left]
    while left < right:
        while input[right] >= key_value and left < right:
            right -= 1
        input[left] = input[right]

        while input[left] <= key_value and left < right:
            left += 1
        input[right] = input[left]

    input[left] = key_value
    quickSort2(input, min_index, left - 1)
    quickSort2(input, left + 1, max_index)

每一趟排序如下:

[1, 10, 99, 23, 43, 11, 2] 左指针: 0  右指针: 0
[1, 10, 99, 23, 43, 11, 2] 指针: 0
[1, 2, 99, 23, 43, 11, 99] 左指针: 2  右指针: 6
[1, 2, 99, 23, 43, 11, 99] 左指针: 2  右指针: 2
[1, 2, 10, 23, 43, 11, 99] 指针: 2
[1, 2, 10, 11, 43, 43, 99] 左指针: 4  右指针: 5
[1, 2, 10, 11, 43, 43, 99] 左指针: 4  右指针: 4
[1, 2, 10, 11, 23, 43, 99] 指针: 4
[1, 2, 10, 11, 23, 43, 99] 左指针: 5  右指针: 5
[1, 2, 10, 11, 23, 43, 99] 指针: 5
[1, 2, 10, 11, 23, 43, 99]

可以对比一下hoare的具体排序步骤。

前后指针法

在搜索挖坑和hoare方法的时候看到了一篇写的很好的快排博客,引用

http://t.csdn.cn/tzWUS

详细介绍了前后指针法:
在这里插入图片描述
代码如下:

def quickSort3(input, left, right):
    if left>=right:
        return
    pre = left
    cur = left+1
    key_value = input[left]
    
    while cur <= right:  # 改变了结束循环的条件
        if input[cur] <= key_value:
            pre += 1
            input[pre], input[cur] = input[cur], input[pre]
        cur+=1

    input[pre],input[left] = key_value,input[pre]
    quickSort3(input, left, pre - 1)
    quickSort3(input, pre + 1, right)

个人把pre理解为分界线,在它左边的是比input[left] = key_value小或是等于的值。每一次cur找到一个更小的值,就把分界线pre往右边移动一位,然后将pre指向的元素与cur交换,使得pre左边继续保持比key_value更小或等于的状态。

  1. while cur <= right是方法的结束条件,因为最后一个值有可能需要换到pre左边,所以=不要忘记。
  2. pre分界线包括pre所指向的元素,即[left,pre]范围内所有元素小于等于key_value。所以当循环结束时,input[pre]input[left]可以互换位置,将key_value换到分界线上面来。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值