在学习快速排序之前我们要先学一下递归:
1.递归:简而言之就是函数调用自身
1.1举个栗🌰(例)子:求n的阶乘(n!)
代码如下:
#递归的应用:求n的阶乘(n!)
#5!=5*4!
#4!=4*3!
#3=3*2!
#2=2*1!
#1=1*1!
def fun_jc(n:int):
#确定递归的边界
if n == 1:#如果n为一则返回一
return 1
#编写递归的前进段和返回段
return n*fun_jc(n-1)#递归调用
jc = fun_jc(5)#5的阶乘(5!)
print(f'5的阶乘是:{jc}')
运行结果:
调用过程如下:
不够清楚的话再来一个🌰:
1.2用递归实现斐波那契数列(黄金分隔数列):
1.2.1那么...什么是斐波那契数列呢???
代码如下:
def Fibonacci(n:int):
if n == 1 or n == 2:
return 1
else:
return Fibonacci(n-1) + Fibonacci(n-2)
result = Fibonacci(6)#调用Fibonacci
print(result)
运行结果:(取6)
理解完递归之后,再来看看快速排序是如何实现的。
2.快速排序:
基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序。快排设计到递归,先来认识以下递归。
快速排序代码:
# 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,
# 则可分别对这两部分记录继续进行排序,以达到整个序列有序。
# 1. 以最左边的元素作为基准数
# 2. 先从最右边开始找比基准数小的数,找到之后停下来
# 3. 从最左侧往右找比基准数大的数,找到之后停下来
# 4. 交换两个位置的值
# 5. 继续从当前位置执行1、2、3步骤,直到左右两个位置重合之后停下来
# 6. 交换基准数和重合位置的值, 基准数归位, 基准数左边的都比基准数小, 基准数右边的都比基准数大
# 7. 以基准数为界,把列表拆分为两个字列表然后分别进行,上述操作,直到排序完成
# 因为我们无法确定排序的次数和从哪开始拆分列表所以无法使用循环解决这个问题, 所以只能使用递归
# 如果使用递归的话, 那么必须要有函数,才能递归
# 参数
# 参数1: 排序的列表是谁
# 参数2: 左边的位置(指针)
# 参数3: 右边的位置(指针)
# 返回值
# 不需要
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
count = 0#计数器
def qucik_sort(arr:list=arr,left:int=0,right:int = len(arr)-1):#
global count# 声明我们要使用全局变量
count += 1
#当我们左右指针重合或者超过的时候, 那么说明拆分的列表长度是1了, 只有一个元素的情况下, 我们就不需要排序了
if left >= right:
return #合法性判断
#定义变量:定义基准数和左右的指针位置
base_num = arr[left]#定义基准元素为左边
low = left#可以看成定义了一个指针指向这组数的左边
high = right#可以看成定义了一个指针指向这组数的右边
print(f'交换前:{arr}')
#继续从当前位置执行1、2、3步骤,直到左右两个位置重合之后停下来
while low < high:#左边的指针指的元素小于右边指针指的元素
# 1. 先从最右边开始找比基准数小的数,找到之后停下来
while low <high and arr[high]>=base_num:#基准元素比high指针小
high -= 1
print(f'右边的指针{high}')
# 2. 从最左侧往右找比基准数大的数,找到之后停下来
while low<high and arr[low] <= base_num:#基准元素比low指针大
low += 1
print(f'左边的指针{low}')
#3. 交换两个位置的值
arr[low],arr[high] = arr[high],arr[low]
print(f'交换后:{arr}')
#交换基准数和重合位置的值, 基准数归位, 基准数左边的都比基准数小, 基准数右边的都比基准数大
arr[low],arr[high] = arr[high],base_num
print(f'基准数归位:{arr}')
#以基准数为界,把列表拆分为两个字列表然后分别进行,上述操作,直到排序完成
#调用函数,左边的列表
qucik_sort(arr,left=left,right=high-1)
#调用函数,右边的列表
qucik_sort(arr,left=low+1,right=right)
qucik_sort()
print(f'执行次数:{count}')
快速排序运行结果: