递归与二分查找

递归与二分查找

一、递归

  • mac上的python最大递归深度997次,但python官方文档上的最大递归深度是1000
def func(count):
	print("递归第%d" % count)
	func(count+1)
func(1)
# 结果是:
......
递归第994次
递归第995次
递归第996次
[Previous line repeated 993 more times]
  File "/Volumes/workspace/python-study/re_st/递归与二分查找.py", line 2, in func
    print("递归")
RecursionError: maximum recursion depth exceeded while calling a Python object

  • 设置最大的递归深度
import sys
sys.setrecursionlimit(10000)
# 可以设置递归深度,但是程序不一定能跑到

二、利用递归和os模块遍历所有的文件和文件夹

import os
# 树结构、遍历树结构
filepath = '/Volumes/workspace'
def read(filepath, n):
	# 设置递归深度n
	l = os.listdir(filepath)
	# # os.listdir()查看的是当前路径下的文件夹列表,这一点非常重要,拿到路径后第一步就是获取列表
  # 并且这一步必须放在函数内反复调用
	# print(l.__iter__())
	# # 列表
	# print('__iter__' in dir(l))
	# # 是可迭代的
	# print('__next__' in dir(l))
	# 但不是迭代器
	for file in l:
		if os.path.isdir(os.path.join(filepath, file)) and '.' not in file: 
		# 判断是文件夹还是文件并且不是点号开头的文件夹
    # os.path.join(filepath, file)拼接上一层文件路径和当前的文件夹名,形成当前文件夹的路径
			print('\t'*n, file)
			# 根据深度和制表符来控制缩进,显示文件夹之间的层次关系
			# 打印文件夹的名字,
			read(os.path.join(filepath, file), n + 1)# 递归的入口
			# 如果是文件夹,再次循环是深度加1
		else:
			print('\t'*n, file) # 递归的出口
			# 根据深度和制表符来控制缩进,显示文件与文件夹之间的层次关系

read(filepath, 0)
# 递归深度为0

三、二分查找法

'''二分查找'''
# # 二分查找的前提必须是被查找的对象是有序的
l = [1,2,4,42,2,23,35,32,5,4,3,3256,23,233254,32, 312242, 132132,123, 213]
s = set(l)
l = list(s)
l = sorted(l, key=lambda x : x, reverse=False)
# key对应的函数返回的值应该是排序依据的内容的值,sorted()函数会对这些返回值来排序,
# 在根据返回值的顺序排列整个对象的顺序
# 去重
print(l)
'''方法一:while True无限循环'''
# count = 1
# n = 4
# left = 0
# right = len(l) - 1
# while left <= right:
# 	middle = (left + right) // 2
# 	# 查找中间位置,必须用//,确保是整数值
# 	if n < l[middle]:
# 		right = middle - 1
# 		# 如果查找的值小于中间位置的值,那么值在左边,把right变成middle-1
# 	elif n > l[middle]:
# 		left = middle + 1
# 		# 如果查找的值大于中间位置的值,那么值在右边,把left变成middle+1
# 	else:
# 		print(count)
# 		print('查找%d后找到,位置在%d' % (count,middle))
# 		break
# 		# 如果整好等于中间位置的值,输出索引值,并退出程序
# 	count += 1
# else:
# 	print('查找目标不在对象里')
# # 循环结束还未找到,那么目标不在查找的对象里

'''方法二:迭代'''

def func(left, right, n, count):
	if right >= left:
		# 必须规定right >= left,等于时候说明只有一个元素,反之则查找失败
		middle = (left + right) // 2
		if n < l[middle]:
			right = middle - 1
		elif n > l[middle]:
			left = middle + 1
		elif n == l[middle]:
			print ('查找%d次,找到位置在%d' % (count, middle))
			return '查找成功'
		count += 1
		return func(left, right, n,count)
	else:
		return -1
		# 列表中都是数字,在查找不到的时候返回数字-1,表示找不到,比较规范
print(func(0, len(l) - 1, 2, 1))
# 利用递归来实现二分法查找,上边的程序必须在递归之前先进行判断,要查找的值是否在
# 查找对象中,不存在直接返回失败,这个程序必须有,没有的话值又不在对象中,系统会报
# 超过最大递归深度的错误。
posted @ 2020-01-13 16:31  大道至诚  阅读(151)  评论(0编辑  收藏  举报