1)我们使用的词典,本身就是递归,为了解释一个词,需要使用更多的词。当你查一个词,发现这个词的解释中某个词仍然不懂,于是你开始查这第二个词,可惜,第二个词里仍然有不懂的词,于是查第三个词,这样查下去,直到有一个词的解释是你完全能看懂的,那么递归走到了尽头,然后你开始后退,逐个明白之前查过的每一个词,最终,你明白了最开始那个词的意思。
2)多年前我五岁的儿子问我「不是每条船都有救生艇的吧?」「怎么会呢?」「也许救生艇上会有一艘更小的救生艇,但是那艘小艇上可能就没有更小的救生艇了。」
3)一个洋葱是一个带着一层洋葱皮的洋葱。
- # 3 + 2 + 1
- def sum_numbers(num):
- # 1.如果是1,直接返回1 -- 出口
- if num == 1:
- return 1
- # 2.如果不是1,重复执行累加并返回结果
- return num + sum_numbers(num-1)
-
- # 输出结果为6
- print(sum_numbers(3))
分析:
- # 数字阶乘
- def Fact(n):
- if n == 1:
- return 1
- return n * Fact(n-1)
- # 斐波那契数列
- def Fibo(n):
- # 出口
- if n == 1 or n == 2:
- return 1
- else:
- return Fibo(n - 1) + Fibo(n - 2)
分析:
这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
- # 快速排序
- def partition(li,left,right):
- tmp = li[left]
- while left < right:
- while left < right and li[right] >= tmp: #从右边找比tmp小的数
- right -= 1 #继续从右往左查找
- li[left] = li[right] #把右边的值写到左边空位上
-
- while left < right and li[left] <= tmp:
- left += 1
- li[right] = li[left] #把左边的值写到右边空位上
-
- li[left] = tmp #把tmp归位
- return left
- def quick_sort(li,left,right):
- if left < right : #至少两个元素
- mid = partition(li, left, right)
- quick_sort(li, left, mid-1)
- quick_sort(li, mid+1, right)
- li = [5, 7, 4, 6, 3, 1, 2, 9, 8]
- quick_sort(li, 0, len(li)-1)
- print(li)
1)快速排序是一个不稳定的排序算法
2)时间复杂度
平均:O(nlogn)
最差:O(n2),退化为冒泡排序
归并排序用的是分治法,把一个大问题化解为k个中问题,每个中问题再化解为k个小问题,直至问题化为最小可解的问题。对这些问题求解,再不断地合并结果,直至合并完毕。
- # 归并排序
- # 1.将整个数组对半分开,直到只剩一个元素
- # 2.从一个元素开始往回进行对比合并,将合并的内容暂且放在一个空列表中
- # 定义合并merge函数
- def merge(L,R):
- # 将两个排过序的两个列表进行合并并排序
- # 分别用于限定L、R的数据减少情况
- i, j = 0,0
- # 用于存放L与R的合并内容
- res = []
- while i < len(L) and j < len(R):
- # 如果左边的数大于右边的数,就将左边的数先添加到res中,再继续比较(合并的R、L已经排过序)
- # 如果如果右边的数大于左边的数,就将右边的数先添加到res中,再继续比较(合并的R、L已经排过序)
- if L[i] <= R[j]:
- res.append(L[i])
- i += 1
- else:
- res.append(R[j])
- j += 1
- # 因为当 i == len(L) 或者 j == len(R)时,跳出while循环,且每次循环只处理一个列表里的内容,所以其中有一个列表内容会先全部加入res中,另一个列表还剩内容未加进res中。
- # 对未处理完的列表,直接加入res中
- res += R[j:] if i == len(L) else L[i:]
- return res
-
- # 定义排序merge_sort函数
- def merge_sort(List):
- length = len(List)
- if length <= 1:
- return List
- else:
- mid = length//2
- left = merge_sort(List[:mid])
- right = merge_sort(List[mid:])
- return merge(left,right)
-
-
- if __name__ == '__main__':
- List = [9,8,7,5,3,6,11,2,4,1,12]
- print(merge_sort(List))
不管待排序列表的初始状态如何,都不影响排序的时间复杂度。归并排序一直对待排序列表进行拆分,需要进行logn次拆分,在每一次递归合并中,需要进行n次比较和添加。时间复杂度为 T(n)=nlogn ,再乘每次操作的步骤数(常数,不影响大O记法),所以归并排序的时间复杂度为 O(nlogn) 。
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
第一次循环:

第二次循环:

第三次循环:
第四次循环:
- # 冒泡排序
- def func_sort(n):
- for i in range(n-1): # 控制排序次数
- for j in range(n-1-i): # 控制比较次数
- if L[j]>L[j+1]:
- print('{}比{}大,交换前{}'.format(L[j], L[j + 1], L))
- L[j], L[j + 1] = L[j + 1],L[j]
- print('交换后:{}'.format(L))
- else:
- print("我不用交换{}".format(L))
- print('排序后的列表为:{}'.format(L))
- func_sort(len(L))
时间复杂度是O(n^2),是一种稳定的算法
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,所以称为:选择排序
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

- # 插入排序
- def insertion_sort(sort_list):
- # 注意是从第二个位置开始向前插入元素
- for i in range(1, len(sort_list)):
- # 从第i个元素开始向前比较,如果小于前一个元素,交换位置
- for j in range(i, 0, -1):
- if sort_list[j] < sort_list[j - 1]:
- sort_list[j - 1], sort_list[j] = sort_list[j], sort_list[j - 1]
-
-
- test_llst = [5, 4, 6, 3, 1, 2]
- print(test_llst)
- insertion_sort(test_llst)
- print(test_llst)
最优时间复杂度:O(n)
最坏时间复杂度:O(n2)
二分搜索是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

- # 二分查找
- lss = [12, 27, 29, 32, 35, 54, 60, 70, 71, 91]
- def b_search(ls, target):
- def bin_search(ls, target, l, r):
- if l > r:
- return -1
- mid = int(l + (r - l) / 2)
- if ls[mid] == target:
- return mid
- elif ls[mid] < target:
- return bin_search(ls, target, mid + 1, r)
- else:
- return bin_search(ls, target, l, mid - 1)
- return bin_search(ls, target, 0, len(ls)-1)
- print(b_search(lss, 70))
- print(b_search(lss, 222))
二分查找的时间复杂度为O(log2n)
1.Python实现快速排序_想成大神的大艳的博客-CSDN博客_快速排序python
2.归并排序(Python代码)_莱维贝贝、的博客-CSDN博客_python 归并排序