快速排序算法/排序算法总结

快速排序的思路:不像插入排序和选择排序那样把序列看成两个部分,而是看元素最终放到有序序列的哪个位置。

如下直接查找54应该在那个位置,54左边都应该比54小,而54右边都因该比54大,所以设置两个游标low和游标high,当两个游标交汇的地方就是54所应该在的位置:

过程如下:

1.第一趟排序

刚开始的时候,如下:

low不断往前移动(只要数据小于54就不断往右移,直到遇到比54大的数才停止),high不断往左移动(只要数据大于54就不断往前移动)。

移动的结果如下:

这样就不能动了,怎么办呢?答案是让20和93交换位置,这样不就能继续移动了吗,结果如下:

之后low下标和high下标继续移动,结果如下:

然后再次交换位置,结果如下:

之后继续移动,直到low到达77位置,这时low和high交汇,这时low(77)前面的位置就是54应该在的位置。

结果如下:

第一趟排完之后54左边的都比他小,54右边的都比他大

通过54把序列分成两个部分。

2.第二趟排序

通过54把序列分成两个部分,第二趟排26,26左边的都比26小,26右边的都比26大。

结果如下(图可能有出入,记住排序的思想就行):

3.第三趟排序

通过54把序列分成两个部分,第三趟排44,44左边的都比44小,44右边的都比44大。

结果如下:

经过上面的排序之后26,54,44所在序列中的位置就是他在有序序列中的真实位置。

4.后几趟排序原理相同。

代码实现的思路:

过程如下:

1.刚开始时候如下:

把54给了mid_value保存起来,结果如下:

然后把high所指位置的数据放到low位置上来,结果如下:

如果high位置的数据小于中间值mid_value的话,就让low的位置的数据等于high位置的数据,如下:

因为经过以上判断low位置的数据肯定比自己选定的那个数据要小,所以low的下标直接加一,如下:

之后low的下标继续往后移动,如果移动过程中的数据比54小的话,那么数据继续往前移动,结果如下:

否则如果low遇到的位置数据比54大的话,那么就把low位置的数据放到右边。

因为移动过去的数据比54要大所以不用再判断93的大小,然后让high的位置往左移动一位,结果如下:

然后low的位置为空没存数据,之后low停止,让high往左走,如果high位置所指的元素比54大的话那么high指针就继续往左移动。直到遇到比54小的数据时再停止。

high在往左移动的过程中,如果遇到比54小的数据的话,就把该数据放到左边low指针所指的位置。结果如下:

之后low位置的下标再加一,然后判断low位置所指的数据跟基准元素大小的比较。

low下标所指元素77比54大所以把77挪到右边元素的位置。结果如下:

然后high的下标再往左挪,结果如下:

因为31比54要小,所以把31放到把31放到low位置。之后low+=1,这是low与high重合结果如下:

low和high重合之后,让该位置的数据等于54,结果如下:

这是54左边的元素都比54小,54右边的元素都比54要大,结果如下:

之后把54左边视为一个子序列,54右边的数据视为一个子序列,然后以同样的方式进行排序。

排序过程中如果遇到54的话,要不就把54都放在mid_value(54)位置的左边,要不就都把他们放在右边,不要一边一个:

所以把等于的情况放到一边去处理,结果如下:

执行如下代码结果为:[20, 26, 44, 17, 31, 31, 77, 55, 93]

不是完整的代码

def quick_sort(alist):
    mid_value = alist[0]  # 刚开始把第一个位置的元素给了mid_value
    low = 0  # 把low的起始下标设置为0
    n = len(alist)
    high = n - 1  # 把high的起始下标设置为最后一个数

    while low<high:
        while low < high and alist[high] > mid_value:  # 在low<high并且high所指位置元素比mid_value大的情况下,让high往左移动
                high -= 1
        alist[low]=alist[high]   #不满足上面条件的话,就把high位置的数据给了low,然后low+1
        low+=1

        #之后就应该执行low的操作
        while low<high and alist[low]<mid_value: #当low小于high,并且low位置所指的元素比mid_value小的话low就继续往右移动
            low+=1
        alist[high]=alist[low]   #不满足上面条件就执行下面操作。
        high-=1                  #到这个位置如果没加上层循环的话就会执行完毕不在往下执行。所以加上循环while low<high

if __name__ == '__main__':
    alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    quick_sort(alist)
    print(alist)

下面代码是相对比较完整的代码:

def quick_sort(alist):
    mid_value = alist[0]  # 刚开始把第一个位置的元素给了mid_value
    low = 0  # 把low的起始下标设置为0
    n = len(alist)
    high = n - 1  # 把high的起始下标设置为最后一个数

    while low<high:
        while low < high and alist[high] > mid_value:  # 在low<high并且high所指位置元素比mid_value大的情况下,让high往左移动
                high -= 1
        alist[low]=alist[high]   #不满足上面条件的话,就把high位置的数据给了low,然后low+1
        low+=1

        #之后就应该执行low的操作
        while low<high and alist[low]<mid_value: #当low小于high,并且low位置所指的元素比mid_value小的话low就继续往右移动
            low+=1
        alist[high]=alist[low]   #不满足上面条件就执行下面操作。
        high-=1                  #到这个位置如果没加上层循环的话就会执行完毕不在往下执行。所以加上循环while low<high
    alist[low]=mid_value
if __name__ == '__main__':
    alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    quick_sort(alist)
    print(alist)

猜你喜欢

转载自blog.csdn.net/qq_39112101/article/details/88600042