这是本人第一次写博客,嗯...目的就是想记录一下自己的学习过程。以前学习数据结构的时候写快排用的循环都是双重for循环,今天偶尔看到了运用递归来实现快速排序,所以突发想记录一下。由于我以前学过c和java,现在在自学python,所以一下代码均为python。但基本思想是一样的。
1.递归思想
假设我们用递归来实现n!。
def digui(n):
if n>1:
return n*digui(n-1)
else:
return n
def main():
n=eval(input("请输入你要计算阶乘的数字:"))
print(digui(n))
main()
递归必须要有基线条件和递归条件,如果没有基线条件,结果会导致无法返回的结果。什么叫基线条件呢,说白了就是告诉他什么时候停止递归,该结束了。在实现n!是n=1就是基线条件。
假设我们输入5,此时调用digui()函数,以n为5传入,此时n>1,返回 5*digui(4),由于没有到达基线条件,所以又调用digui()函数
接着n为4传入 ,此时n>1,返回 4*digui(3), .......
...... 直到n=1时, 此时n=1,返回1
最后在依次将2,3,4返回给上一层。然后打印输出,这就是递归。当然还有一种是尾递归,这里不做说明。
2.回顾快速排序
如果对快速排序还不是很清楚的,可以尝试看一下其他博主讲的快速排序
https://blog.csdn.net/nrsc272420199/article/details/82587933
3.递归实现快速排序
要用递归实现快速排序,我们上面说过递归必须要有基线条件和递归条件
首先我们来看,假设没有数字 数组为空 【 】,此时不需要排序
假设有一个数字,【5】,此时也不用排序
两个数字【5,4】,如果按照某一特定顺序(依据题的情况,比如这就是从大到小)就不用排序,但是从小到大就需要啦,到此我们已经找到了基线条件,发现没有,但数组的个数为0或者1是,我们就要停止递归啦。
三个数字的时候呢?【5,1,2】我们把5作为基准值,则此时应该被分为三个区域
【大于5的所有】【5】【小于5的所有】此时变成【1,2】【5】【空】,接着继续对左边的进行以上操作,选取基准值【1】,左边就会被分成【】【1】【2】。而右边的为空,已经到达基线条件,结束了。
同理,四个数字...五个数字...n个数字
假设待排序数组为list【10,5,2,3】,快排函数是quicksort()
(1)首先调用quicksort(list)
(2)选取基准值-------这里是【10】
(3)分区返回----------即大于10的和小于10的-------------则list变为【5,2,3】【10】【】
我们保留中间,在让左边和右边进入quicksort()-----此时右边为空结束
进入quicksort(【5,2,3】),继续进行(1)(2)(3)直到都结束
def quicksort(list):
less=[]
greater=[]
if len(list)<2:
return list
else:
prio=list[0]
for i in list[1:]:
if i>prio:
less.append(i)
else:
greater.append(i)
return quicksort(less)+[prio]+quicksort(greater)
def main():
list=[]
n=eval(input("请输入你要输入的数字个数:"))
for i in range(0,n):
m=eval(input("请输入第{:}个数字".format(i+1)))
list.append(m)
print(quicksort(list))
main()
下面是代码优化简写
def quicksort(list):
if len(list)<2:
return list
else:
prio=list[0]
less=[i for i in list[1:] if i<=prio]
greater=[i for i in list[1:] if i>prio]
return quicksort(less)+[prio]+quicksort(greater)
def main():
list=[]
n=eval(input("请输入你要输入的数字个数:"))
for i in range(0,n):
m=eval(input("请输入第{:}个数字".format(i+1)))
list.append(m)
print(quicksort(list))
main()
初次学习,欢迎交流学习,欢迎各位大佬优化和指出错误。