时间复杂度O(N*logN)
额外空间复杂度O(logN)
可以用荷兰国旗问题来改进快速排序==>随机
把一个数组分为较小和较大的2个子序列,然后递归地排序两个子序列
经典快排
- 挑选基准值:从数列中挑出一个元素,称为"基准"(pivot)
- 分割:重新排序数列
- 所有比基准值小的元素摆放在基准前面
- 所有比基准值大的元素摆在基准后面
- 与基准值相等的数可以到任何一边(或者中间)
 
- 在这个分割结束之后,对基准值的排序就已经完成
- 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序;
选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响(使用随机)
 
class QuickSort(object):
    """
    快排
        经典快排
        随机快排
    """
    def run(self, arr: list):
        if arr is None or len(arr) < 2:
            return
        self.quick_sort(arr, 0, len(arr) - 1)
    def quick_sort(self, arr, L, R):
        if L < R:
            p = self.partition(arr, L, R)
            self.quick_sort(arr, L, p[0] - 1)
            self.quick_sort(arr, p[0] + 1, R)
    def partition(self, arr: list, L: int, R: int):
        less = L - 1
        more = R
        while L < more:
            if arr[L] < arr[R]:
                arr[less], arr[L] = arr[L], arr[less]
                less += 1
                L += 1
            elif arr[L] > arr[R]:
                arr[more], arr[L] = arr[L], arr[more]
                more -= 1
            else:
                L += 1
        arr[more], arr[R] = arr[R], arr[more]
        return [less + 1, more]
list_ = [1, 3, 3, 5, 4, 2, 1, 5, 8, 7, 9]
result = QuickSort().run(list_)
print(result)
class QuickSortPython:
    def partition(self, arr, low, high):
        i = low - 1  # 最小元素索引
        pivot = arr[high]
        # pivot = random.choice(arr)  # 随机快排
        for j in range(low, high):
            if arr[j] <= pivot:  # 当前元素小于或等于 pivot
                i += 1
                arr[i], arr[j] = arr[j], arr[i]
        arr[i + 1], arr[high] = arr[high], arr[i + 1]
        return i + 1
    def sort(self, arr, low, high):
        """
        :param arr: 排序数组
        :param low: 起始索引
        :param high: 结束索引
        :return:
        """
        if low < high:
            pi = self.partition(arr, low, high)
            self.sort(arr, low, pi - 1)
            self.sort(arr, pi + 1, high)
        return arr
list_ = [1, 3, 3, 5, 4, 2, 1, 5, 8, 7, 9]
result = QuickSortPython().sort(list_, 0, len(list_) - 1)
print(result)
荷兰国旗
给定一个数组arr,和一个数num
请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。
要求额外空间复杂度O(1),时间复杂度O(N)
class HeLanGuoQi(object):
    """荷兰国旗问题"""
    def partition(self, arr: list, num: int):
        cur = 0
        less = - 1
        more = len(arr) - 1 + 1
        while cur < more:
            if arr[cur] < num:
                less += 1
                arr[less], arr[cur] = arr[cur], arr[less]
                cur += 1
            elif arr[cur] > num:
                more -= 1
                arr[more], arr[cur] = arr[cur], arr[more]
                # cur -= 1 # TODO: 注意这里cur不动
            else:
                cur += 1
        # 返回等与区域的左边界和右边界
        return [less + 1, more - 1]
数组分组
给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。
要求额外空间复杂度O(1),时间复杂度O(N)
 
             
           
             
                         
             
            
评论区