算法图解

chapter1 二分查找

#1.2二分查找
def binary_search(list,item):
    low = 0
    hight = len(list)-1

    while low <= hight:#只要范围没有缩小到只包含一个元素
        mid = (low + hight) // 2 # 向下取整也可以使用int(x)的形式
        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#假设最小元素的索引为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 递归

##3.1递归
#寻找盒子中的钥匙
"""方法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")

##3.2 基线条件和递归体条件
"""
编写递归函数是,必须设置结束条件
递归函数包含两部分:
    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
#3.3 栈
"""
栈的两种操作:压入和弹出
所有函数调用都进入调用栈
调用栈可能很长,这将占用大量的内存
"""
#3.3.1 调用栈
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") #调用函数变量“maggie”存储到内存中,打印    hello, maggie !
                    #调用函数greet2,打印 how are you, maggie ?greet函数暂停并处于未完成状态
                     # 执行玩greet2后返回greet 打印 getting ready to say bye...
                      #在调用函数bye 打印ok bye!
hello, maggie !
how are you, maggie ?
getting ready to say bye...
ok bye!

#3.3.2 递归调用栈
def fact(x): #x!
    if x == 1:
        return 1
    else:
        return x * fact(x-1)    #递归调用

6

chapter 4快速排序

##4.1分而治之(divide and conquer,D&C)
"""
分而治之是一种通用的算法
分而治之解决问题的过程包括两个步骤(工作原理):
    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] #del删除的是变量,而不是数据
    return sum(arr)+a
print(sum([2,4,6]))
12
12
12
##练习
#4.2 编写一个递归函数来计算列表包含的元素数
def lenList(list):
    if list == []: #基线条件:列表中的元素是否为空
        return 0
    else:
        return 1+lenList(list[1:])

print("列表包含的元素个数为:",lenList([2,4,6]))
列表包含的元素个数为: 3

#4.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
#4.4递归实现二分查找

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]
#print(len(a))
user_input = int(input("请输入你要查询的值:"))


left = 0
right = len(a)-1

index = HalfSearch(a, user_input, left, right)#调用递归二分查找算法
print(index)
请输入你要查询的值:3
2
#4.2 快速排序
"""
快速排序算法也运用了分而治之的思想
快速排序算法的步骤:
    step1.选择基准值
    step2.将数组分成两个子数组:小于基准值的元素和大于基准值的元素
    step3.对这两个子数组进行快速排序

"""
def quickSort(arr):
    if len(arr)<2:
        return arr #基线条件:空的或只包含一个元素的数组是“有序”的
    else:
        pivot = arr[0] #递归条件(pivot)为基准值
        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]
#4.3 大O
"""
c*n:c是算法所需的固定时间量
快速查找的常量比合并查找小,虽然运行时间都为O(nlogn),快速查找的速度将更快

"""

chapter 5 散列表

#5.1 散列函数
"""
散列函数:将输入映射到数字

eg:商店售货员如何快速的知道商品的价格
1.创建一个空数组
2.将商品名字(苹果)加入到数组中,散列函数输出为3,故商品(苹果)的价格存储到数组的索引3处
...

散列函数:将同样的输入映射到相同的索引,将不同的输入映射到不同的索引,知道数组的大小,只返回有效的索引

"""

"""
散列表:散列函数+数组
散列表使用散列函数来确定元素的存储位置
散列表也被称作散列映射、映射、字典和关联数组(python提供的散列表表现为字典)
散列表由键和值组成
"""

#5.2 应用案例
"""
5.2.1 将散列表用于查找
"""
#text01
book = dict()
book['apple'] = 0.67
book['milk'] = 1.49

print(book['apple'])
0.67

#text02
phone_book = {
     } #创建散列表的快捷方式
phone_book['jenny'] = 864321
phone_book['emergency'] = 911
print(phone_book['jenny'])

864321
#5.2.2 防止重复
voted = {
     } #创建一个空的散列表

def check_voter(name):
    if voted.get(name): #get函数返回指定键的值
        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!
#5.2.3 散列表作为缓存
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

在这里插入代码片

#5.2.4 小结
"""
散列表适用于:模拟映射关系;防止重复;缓存数据
"""

##5.3 冲突 & 5.4性能
"""
冲突:给两个分配的位置相同
处理冲突最简单的方法:如果两个键映射到同一个位置,就在这个位置存储一个链表
避免冲突:较低的填装银子,良好的散列函数
一旦填装银子超过0.7,就调整散列表的长度
"""
#练习5.5
tel = {
     }

tel['Esther'] = 123
tel['Ben'] = 234
tel['Bob'] = 456
tel['Dan'] = 678

print(tel['Bob'] )

456
#练习5.6

power = dict()

power['A'] = 10
power['AA'] = 100
power['AAA'] = 500
power['AAAA'] = 1000


print(power['AA'])

100
#练习5.7
book = dict()

book['Apple'] = 'Maus'
book['Bob'] = 'Fun Home'

print(book['Bob'])
Fun Home

chapter6.广度优先搜索

#6.1 图简介
""""
解决最小路径问题:(广度优先搜素算法)
    1.使用图连建立问题模型
    2.使用广度有限搜索解决问题
"""
#6.2 图是什么
"""
图模拟一组连接,图由节点和边组成,一个节点可能与众多节点直接相连,这些节点被称作邻居
"""
#6.3 广度优先搜索
"""
广度优先搜索可以解决两类问题:
    1.从节点A出发,有前往节点B的路劲吗?
    2.从节点A出发,前往节点B的哪条路径最短?
广度优先搜索需要按添加顺序进行检查,用队列来实现
队列只支持两种操作:入队和出队
队列(FIFO)是先进先出,栈(LIFO)是后近先出
广度有限搜索的运行时间为O(V+E),其中V为顶点数,E为边数
使用拓扑排序创建一个有序的列表
树是一种特殊的图,没有往后指的边
"""

"""------从人际关系网中找到芒果销售商------"""
#6.4 实现图
"""
有向图的边为箭头,箭头的方向指定了关系的方向
无向图的边不带箭头,其中的关系是双向的
"""
# graph ={} #散列表是无序的
# graph["you"] = ["alice","bob","claire"]
# graph["bob"] = ["anuj",'peggy']
# graph["claire"] = ["thom","jonny"]
# graph["anuj"] = []
# graph["peggy"] = []
# graph["thom"] = []
# graph["jonny"] = []
"""------从人际关系网中找到芒果销售商------"""
#6.5 实现算法
from collections import deque #使用函数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] #将name的邻居都加入到这个搜索队列
    print(search_queue)

    searched = [] #记录检查过的人
    while search_queue: #如果队列不为空
        person = search_queue.popleft() #就取出其中一个人 popleft是用于collections中
        print(person)
        # print(search_queue)

        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!

你可能感兴趣的:(算法)