快速排序(单路快排/双路快排/三路快排) Python版笔记

1.快速排序

时间复杂度 :最好O(nlogn),最坏O(n^2)
空间复杂度 :O(1)

在这里插入图片描述
Partition主要思想是:将小于v和大于v的部分都放到索引值i的左边

def _partition(nums,l,r):
    '''
    将数组第一个数视为base,目的是将所有小数放到左边,大数放到右边,返回正确分割的索引
    '''
    base = nums[l]  #即图片的v
    j = l+1
    for i in range(l+1, r+1):
        if nums[i] < base:  #遍历数组剩下的数,如果小于base则依次放在base的后面
            nums[i], nums[j] = nums[j], nums[i]
            j += 1
        print(nums)
    nums[l], nums[j-1] = nums[j-1], nums[l]   #把base值放到正确的位置
    print(nums)
    return j-1

def _quick_sort(nums,l,r):
    if l < r:
        m = _partition(nums,l,r)
        _quick_sort(nums,l,m-1)
        _quick_sort(nums,m+1,r)


def quick_sort(nums):
    l, r = 0, len(nums)-1
    _quick_sort(nums,l,r)

当待排序数组是一个近乎有序的序列时,容易产生最坏O(n^2)的时间复杂度。
改进办法:base随机选取

def _partition_random(nums,l,r):
    ind = random.randint(l,r)
    nums[l], nums[ind] = nums[ind], [l]
    ##### 后面的内容同_partition,故省略 #####

2.双路快排

当待排序数组是一个数值重复率非常高的序列时,容易产生最坏O(n^2)的时间复杂度。

产生下图所示的情况,左右子树不均衡:
在这里插入图片描述
在这里插入图片描述
Partition主要思想是:将小于v的部分放到指针i(i为遍历用指针)的左边,将大于v的部分都放到指针j的右边,延用随机选base的思路。等于v时使用交换的方式处理。

import random

def _partition_doubule(nums, l, r):
    ind = random.randint(l, r)
    nums[l], nums[ind] = nums[ind], nums[l]
    base = nums[l]
    i, j = l+1, r
    while True:
        while i <= r and nums[i] < base:  # 不能改为nums[i] <= base, 因为这种方式则                      # 会将连续出现的这些值归为其中一方,使得两棵子树不平衡
            i += 1
        while j >= l + 1 and nums[j] > base:  # 不能改为nums[j] >= base.
            j -= 1
        if i > j:
            break
        else:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
            j -= 1
    nums[j], nums[l] = nums[l], nums[j]
    return j


def _quick_sort(nums, l, r):
    if l < r :
        m = _partition_doubule(nums, l, r)
        _quick_sort(nums, l, m - 1)
        _quick_sort(nums, m + 1, r)


def quick_sort(nums):
    l, r = 0, len(nums)-1
    _quick_sort(nums,l,r)

3.三路快排

在这里插入图片描述
Partition主要思想是:将小于v的部分放到指针lt左边,将大于v的部分放到指针gt右边。考虑到v有重复值的情况,遇到等于v的情况,将i指针右移。

import random


def _partition(nums, l, r):
    ind = random.randint(l, r)
    nums[l], nums[ind] = nums[ind], nums[l]
    base = nums[l]
    lt = l  # nums[l+1...lt] < base
    gt = r + 1  # nums[gt...r] > base
    i = l + 1  # nums[lt+1...i] == base
    while (i < gt):
        # i==gt时表示已经比较结束
        if (nums[i] < base):
            nums[i], nums[lt+1] = nums[lt+1], nums[i]
            lt += 1
            i += 1
        elif (nums[i] > base):
            nums[i], nums[gt-1] = nums[gt-1], nums[i]
            gt -= 1
        else:  # nums[i] == base
            i += 1
        print(nums)
    nums[l], nums[lt] = nums[lt], nums[l]
    print(nums)
    return lt, gt


def _quick_sort(nums, l, r):
    if l < r:
        lt, gt = _partition(nums, l, r)
        _quick_sort(nums, l, lt - 1)
        _quick_sort(nums, gt, r)


def quick_sort(nums):
    l, r = 0, len(nums) - 1
    _quick_sort(nums, l, r)

引用:
1.快速排序时间复杂度为O(n×log(n))的证明
2.排序算法—快速排序,随机快速排序和双路快排(python版)
3.归并排序、快速排序、二路快排、三路快排python实现
4.十大经典排序算法(动图演示)

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
很高兴你对Python的学习感兴趣!下面是一些关于黑马Python快速入门的笔记: 1. Python简介:Python是一种高级编程语言,具有简洁、易读和可扩展的特点。它被广泛应用于数据分析、Web开发、人工智能等领域。 2. 安装Python:可以从Python官方网站下载并安装Python解释器。同时,推荐使用Anaconda发行,它包含了很多常用的第三方库和工具。 3. 变量与数据类型:在Python中,可以使用变量来存储不同类型的数据。常见的数据类型包括整数、浮点数、字符串、列表、元组、字典等。 4. 控制流程:使用条件语句(if-else)、循环语句(for、while)和跳转语句(break、continue)控制程序的流程。 5. 函数与模块:函数是一段可重复使用的代码块,可以提高代码的复用性。模块是一个包含Python代码的文件,可以使用import语句导入模块并调用其中的函数。 6. 文件操作:Python提供了丰富的文件操作方法,可以读取和写入文本文件、二进制文件等。 7. 异常处理:通过异常处理机制可以捕获和处理程序中出现的错误,保证程序的稳定性。 8. 面向对象编程:Python是一种面向对象的编程语言,支持类、对象、继承等特性。面向对象编程可以更好地组织和管理代码。 9. 常用第三方库:Python拥有众多的第三方库,可以大大扩展其功能。一些常用的库包括NumPy(数值计算)、Pandas(数据分析)、Matplotlib(数据可视化)等。 以上是关于黑马Python快速入门的一些笔记,希望对你的学习有所帮助。如果有任何问题,请随时向我提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值