chapter1 二分查找
def binary_search(list,item):
low = 0
hight = len(list)-1
while low <= hight:
mid = (low + hight) // 2
guess = list[mid]
if guess == item:
return item
if guess > item:
hight = mid -1
else:
low = mid + 1
return None
my_list = [1,3,5,7,9]
print(binary_search(my_list,3))
print(binary_search(my_list,-1))
3
None
chapter2 选择排序
def selectionSort(arr):
for i in range(len(arr)):
min_idx = i
for j in range(i + 1, len(arr)):
if arr[min_idx] > arr[j]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
arr = [98, 23, 12, 43, 59]
print("排序后的数组:",selectionSort(arr))
排序后的数组: [12, 23, 43, 59, 98]
chaptet3 递归
"""方法1:使用while循环"""
from numpy import empty
def look_for_key(main_box):
pile = main_box.make_a_pile_to_look_through()
while pile is not empty:
box = pile.grab_a_box()
for item in box:
if item.is_a_box():
pile.append(item)
elif item.is_a_key():
print("found the key")
"""方法二:使用递归"""
def look_for_kry(box):
for item in box:
if item.is_a_box():
look_for_key(item)
elif item.is_a_key():
print("found the key")
"""
编写递归函数是,必须设置结束条件
递归函数包含两部分:
1.基线部分(函数不再调用自己)
2.递归条件(函数调用自己)
"""
def countdown(i):
print(i)
if i <= 0:
return
else:
countdown(i-1)
print(countdown(-1))
print(countdown(1))
-1
None
1
0
None
"""
栈的两种操作:压入和弹出
所有函数调用都进入调用栈
调用栈可能很长,这将占用大量的内存
"""
def greet(name):
print("hello, "+name+" !")
greet2(name)
print("getting ready to say bye...")
bye()
def greet2(name):
print("how are you, "+name+" ?")
def bye():
print("ok bye!")
greet("maggie")
hello, maggie !
how are you, maggie ?
getting ready to say bye...
ok bye!
def fact(x):
if x == 1:
return 1
else:
return x * fact(x-1)
6
chapter 4快速排序
"""
分而治之是一种通用的算法
分而治之解决问题的过程包括两个步骤(工作原理):
step1.找出简单的基线条件
step2.确定如何缩小规模,使其符合基线条件
"""
"""
#Q:将一块地均匀分成方块且分出的方块要尽可能大
#A: step1.找出这块地可容纳的最大方块
step2.在剩余的地中找出可容纳的最大方块
step3.一直递归,直至将地分完
"""
def sum(arr):
total = 0
for x in arr:
total += x
return total
print(sum([2,4,6]))
"""
step1:找出简单的基线条件(数组不包含任何元素或只包含一个元素)
step2:缩小规模(计算数组列表中除第一个数字外的其他数字的总和,将其与第一个数字相加)
"""
def sum_rexursion(arr):
if arr == []:
return 0
return arr[0]+sum(arr[1:])
print(sum([2,4,6]))
def sum(arr):
if arr == []:
return 0
a = arr[0]
del arr[0]
return sum(arr)+a
print(sum([2,4,6]))
12
12
12
def lenList(list):
if list == []:
return 0
else:
return 1+lenList(list[1:])
print("列表包含的元素个数为:",lenList([2,4,6]))
列表包含的元素个数为: 3
def find_max(list):
tmp = list.pop(0)
if list == []:
return tmp
max = find_max(list)
if max > tmp:
return max
else:
return tmp
print("找出列表中最大的元素:",find_max([2,4,6,7,9]))
找出列表中最大的元素: 9
def HalfSearch(OrdderedList, key, left, right):
if left > right:
return None
mid = (left + right)//2
if key == OrdderedList[mid]:
return mid
elif key > OrdderedList[mid]:
return HalfSearch(OrdderedList, key, mid+1, right)
else:
return HalfSearch(OrdderedList, key, left, mid-1)
a = [1,2,3,4,5,6,7,8,9]
user_input = int(input("请输入你要查询的值:"))
left = 0
right = len(a)-1
index = HalfSearch(a, user_input, left, right)
print(index)
请输入你要查询的值:3
2
"""
快速排序算法也运用了分而治之的思想
快速排序算法的步骤:
step1.选择基准值
step2.将数组分成两个子数组:小于基准值的元素和大于基准值的元素
step3.对这两个子数组进行快速排序
"""
def quickSort(arr):
if len(arr)<2:
return arr
else:
pivot = arr[0]
less = [i for i in arr[1:] if i<= pivot]
greater = [i for i in arr[1:] if i> pivot]
return quickSort(less) + [pivot] + quickSort(greater)
print("快速排序算法:",quickSort([10,5,2,3]))
快速排序算法: [2, 3, 5, 10]
"""
c*n:c是算法所需的固定时间量
快速查找的常量比合并查找小,虽然运行时间都为O(nlogn),快速查找的速度将更快
"""
chapter 5 散列表
"""
散列函数:将输入映射到数字
eg:商店售货员如何快速的知道商品的价格
1.创建一个空数组
2.将商品名字(苹果)加入到数组中,散列函数输出为3,故商品(苹果)的价格存储到数组的索引3处
...
散列函数:将同样的输入映射到相同的索引,将不同的输入映射到不同的索引,知道数组的大小,只返回有效的索引
"""
"""
散列表:散列函数+数组
散列表使用散列函数来确定元素的存储位置
散列表也被称作散列映射、映射、字典和关联数组(python提供的散列表表现为字典)
散列表由键和值组成
"""
"""
5.2.1 将散列表用于查找
"""
book = dict()
book['apple'] = 0.67
book['milk'] = 1.49
print(book['apple'])
0.67
phone_book = {
}
phone_book['jenny'] = 864321
phone_book['emergency'] = 911
print(phone_book['jenny'])
864321
voted = {
}
def check_voter(name):
if voted.get(name):
print("kick them out!")
else:
voted[name] = True
print("let them vote!")
check_voter("tom")
check_voter("mike")
check_voter("mike")
let them vote!
let them vote!
kick them out!
cache = {
}
def get_data_from_server(ur1):
pass
def get_page(ur1):
if cache.get(ur1):
return cache[ur1]
else:
data = get_data_from_server(ur1)
cache[ur1] = data
在这里插入代码片
"""
散列表适用于:模拟映射关系;防止重复;缓存数据
"""
"""
冲突:给两个分配的位置相同
处理冲突最简单的方法:如果两个键映射到同一个位置,就在这个位置存储一个链表
避免冲突:较低的填装银子,良好的散列函数
一旦填装银子超过0.7,就调整散列表的长度
"""
tel = {
}
tel['Esther'] = 123
tel['Ben'] = 234
tel['Bob'] = 456
tel['Dan'] = 678
print(tel['Bob'] )
456
power = dict()
power['A'] = 10
power['AA'] = 100
power['AAA'] = 500
power['AAAA'] = 1000
print(power['AA'])
100
book = dict()
book['Apple'] = 'Maus'
book['Bob'] = 'Fun Home'
print(book['Bob'])
Fun Home
chapter6.广度优先搜索
""""
解决最小路径问题:(广度优先搜素算法)
1.使用图连建立问题模型
2.使用广度有限搜索解决问题
"""
"""
图模拟一组连接,图由节点和边组成,一个节点可能与众多节点直接相连,这些节点被称作邻居
"""
"""
广度优先搜索可以解决两类问题:
1.从节点A出发,有前往节点B的路劲吗?
2.从节点A出发,前往节点B的哪条路径最短?
广度优先搜索需要按添加顺序进行检查,用队列来实现
队列只支持两种操作:入队和出队
队列(FIFO)是先进先出,栈(LIFO)是后近先出
广度有限搜索的运行时间为O(V+E),其中V为顶点数,E为边数
使用拓扑排序创建一个有序的列表
树是一种特殊的图,没有往后指的边
"""
"""------从人际关系网中找到芒果销售商------"""
"""
有向图的边为箭头,箭头的方向指定了关系的方向
无向图的边不带箭头,其中的关系是双向的
"""
"""------从人际关系网中找到芒果销售商------"""
from collections import deque
graph ={
}
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
def person_is_seller(name):
return name[-1] == 'm'
def search(name):
search_queue = deque()
search_queue += graph[name]
print(search_queue)
searched = []
while search_queue:
person = search_queue.popleft()
print(person)
if not person in searched:
if person_is_seller(person):
print(person + " is a mago seller!")
return True
else:
search_queue += graph[person]
print(search_queue)
searched.append(person)
print(searched)
return False
search("you")
deque(['anuj', 'peggy', 'thom', 'jonny'])
['alice', 'bob', 'claire', 'peggy']
anuj
deque(['peggy', 'thom', 'jonny'])
['alice', 'bob', 'claire', 'peggy', 'anuj']
peggy
thom
thom is a mago seller!