快速排序-

本文详细介绍了快速排序算法的三个版本:1.0、2.0和3.0。1.0版时间复杂度为O(N^2),2.0版改进了1.0版,3.0版引入随机选择划分值,平均时间复杂度优化为O(NlogN)。通过荷兰国旗算法和随机化选择划分元素,实现了排序效率的提升。

快速排序1.0
时间复杂度:O(N^2)

class QuickSort:
    def quick_sort(self, arr):
        if arr is None or len(arr) < 2:
            return
        self.process1(arr, 0, len(arr) - 1)

    def process1(self, arr, l, r):
        if l >= r:
            return
        # l...r partition arr[r]
        # 三部分  [<=arr[l]  arr[r]  >arr[r]
        m = self.partition(arr, l, r)
        self.process1(arr, l, m - 1)
        self.process1(arr, m + 1, r)

    def partition(self, arr, l, r):
        if l > r:
            return -1
        if l == r:
            return l
        less_equal = l - 1
        index = l
        # index < r ,则不包括r位置。
        # 最后,将大于区域的第一个与r交换,此时r是==r的最后一个
        while index < r:
            if arr[index] <= arr[r]:
                less_equal += 1
                self.swap(arr, index, less_equal)
            index += 1
        less_equal += 1  # 大于区域的第一个
        # 最后,将大于区域的第一个与r交换,此时r是==r的最后一个
        # less_equal也就是arr[r]的位置
        self.swap(arr, less_equal, r)
        return less_equal

快速排序2.0
相较于1.0,2.0不用去考虑中间=arr[r]的部分,是1.0的改进
时间复杂度:O(N^2)

class QuickSort:
    def quick_sort2(self, arr):
        if arr is None or len(arr) < 2:
            return
        self.process2(arr, 0, len(arr) - 1)

    def process2(self, arr, l, r):
        if l >= r:
            return
        # l...r partition arr[r]
        # 三部分  [ <=arr[l]  arr[r]  >arr[r] ]
        m = self.netherlandsFlag(arr, l, r)
        self.process2(arr, l, m[0] - 1)
        self.process2(arr, m[1] + 1, r)

    def netherlandsFlag(self, arr, l, r):
        if l > r:
            return [-1, -1]
        if l == r:
            return [l, r]
        less = l - 1  # <arr[R]区域左边界
        index = l  # 从l位置开始遍历
        more = r  # >arr[R]区域左边界,先把r位置包住,partition过程中,r先不动
        while index < more:
            if arr[index] == arr[r]:
                index += 1
            elif arr[index] < arr[r]:
                less += 1
                self.swap(arr, index, less)
                index += 1
            else:
                more -= 1
                self.swap(arr, index, more)
        # l...less  less+1...more-1  more...r-1   r
        # l...less  less+1...more    mor+1...r
        # 最后,将大于区域的第一个与r交换,此时r是==r的最后一个
        self.swap(arr, more, r)
        return [less + 1, more]

    def swap(self, arr, i, j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

快速排序3.0
随机选择一个数i,让arr[i]与arr[r]交换,然后以arr[r]作为选择值,其实就是随机选择一个数i作为划分值,剩下跟快速排序2.0一样
时间复杂度:O(NlogN)

import random
class QuickSort:
    def quick_sort3(self, arr):
        if arr is None or len(arr) < 2:
            return
        self.process3(arr, 0, len(arr) - 1)

    def process2(self, arr, l, r):
        if l >= r:
            return
        # l...r partition arr[r]
        # 三部分  [ <=arr[l]  arr[r]  >arr[r] ]
        self.swap(arr, l+random()*(r-l+1), r)
        m = self.netherlandsFlag(arr, l, r)
        self.process2(arr, l, m[0] - 1)
        self.process2(arr, m[1] + 1, r)

    def netherlandsFlag(self, arr, l, r):
        if l > r:
            return [-1, -1]
        if l == r:
            return [l, r]
        less = l - 1  # <arr[R]区域左边界
        index = l  # 从l位置开始遍历
        more = r  # >arr[R]区域左边界,先把r位置包住,partition过程中,r先不动
        while index < more:
            if arr[index] == arr[r]:
                index += 1
            elif arr[index] < arr[r]:
                less += 1
                self.swap(arr, index, less)
                index += 1
            else:
                more -= 1
                self.swap(arr, index, more)
        # l...less  less+1...more-1  more...r-1   r
        # l...less  less+1...more    mor+1...r
        # 最后,将大于区域的第一个与r交换,此时r是==r的最后一个
        self.swap(arr, more, r)
        return [less + 1, more]

    def swap(self, arr, i, j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值