《算法图解》代码

  1. 二分查找
#coding=utf-8
def binary_search(list, item):
    low = 0
    high = len(list) - 1

        while low <= high:       # While you haven't narrowed it down to one element ...
        mid = (low + high) // 2  # ... check the middle element
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid + 1

    return None                      # Item dosen't exist

my_list = [1, 3, 5, 7, 9]
print (binary_search(my_list, 3))  # 'None' means nil in Python. We use to indicate that the item wasn't found.
  1. 选择排序
#coding=utf-8

# Finds the smallest value in an array
def findSmallest(arr):
    smallest = arr[0]   # Stores the smallest value
    smallest_index = 0  # Stores the index of the smallest value
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def selectionSort(arr):
    newArr = []
    for i in range(len(arr)):
        # Finds the smallest element in the array and adds it to the new array
        smallest = findSmallest(arr)
        newArr.append(arr.pop(smallest))
    return newArr

print(selectionSort([5, 3, 6, 2, 10]))
  1. 递归
    3.1 基线条件 和 递归条件
#coding=utf-8

# 基线条件和递归条件
def countdown(i):
    if i <= 0:    # <---- base case 基线条件
        return
    else:
        countdown(i-1)  # <---- recursive case 递归条件

countdown(5)

3.2 调用栈
这是本节的一个重要概念:调用另一个函数时,当前函数暂停并处于未完成状态

# 调用栈
def greet2(name):
    print("how are you, " + name + "?")

def bye():
    print("ok bye!")

def greet(name):
    print("hello, " + name + "!")
    greet2(name)
    print("getting ready to say bye...")
    bye()

greet("adit")

3.3 递归调用栈-斐波那契

def fact(x):
    if x == 1:
        return 1
    else:
        return x * fact(x-1)

print(fact(5))
  1. 快速排序
    快速排序闭选择排序快很多。
    使用了分而治之(D&C)思想。
    别忘了,你要使用D&C,因此需要将数组分解,直到满足基线条件
def quickSort(array):
    if len(array) < 2:
        return array  # 基线条件:为空或只包含一个元素的数组是“有序”的
    else:
        pivot = array[0]  # 递归条件
        less = [i for i in array[1:] if i <= pivot ]    # 由所有小于基准值的元素组成的子数组
        greater = [i for i in array[1:] if i > pivot ]  # 由所有大于基准值的元素组成的子数组

        return quickSort(less) + [pivot] + quickSort(greater)

print(quickSort([10, 5, 2, 3]))
  1. 散列表
    散列表由键和值组成
    对于同样的输入,散列表必须返回同样的输出,这一点很重要
    使用散列表来检查是否重复,速度非常快

  2. 广度优先搜索

#coding=utf-8
from collections import deque

# 判断一个人是不是芒果销售商
def person_is_seller(name):
    return name[-1] == 'm'  # 检查人的姓名是否以m结尾

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 search(name):
    search_queue = deque()       # 创建一个队列
    search_queue += graph[name]  # 将你的邻居都加入到这个搜索队列中
    searched = []                # 这个数组用于记录检查过的人
    while search_queue:                  # 只要队列不为空
        person = search_queue.popleft()   # 就取出其中的第一个人
        if not person in searched:       # 仅当这个人没检查过时才检查
            if person_is_seller(person):  # # 检查这个人是否是芒果销售商
                print(person + " is a mango seller!")  # 是芒果销售商
                return True
            else:
                search_queue += graph[person]  # 不是芒果销售商。将这个人的朋友都加入搜索队列
                searched.append(person)        # 将这个人标记为检查过
    return False     # 如果到达了这里,就说明队列中没人是芒果销售商

print(search("you"))


7.狄克斯特拉算法

狄克斯特拉算法找出的是 总权重最小的路径
带权重的图称为加权图(weighted graph),不带权重的图称为非加权图(unweighted graph)
要计算非加权图中的最短路径,可使用广度优先搜索。要计算加权图中的最短路径,可使用狄克斯特拉算法
在无向图中,每条边都是一个环。狄克斯特拉算法只适用于有向无环图(directed acyclicgraph,DAG)

包含四个步骤:
(1)找出“最便宜”的节点。即可在最短时间内到达的节点。
(2)更新该节点的邻居开销。
(3)重复这个过程,直到对图中的每个节点都这样做了。
(4)计算最终路径。

#coding=utf-8

# 需要三个散列表和一个数组。
# 散列表:1)图;2)costs:存储每个节点的开销;3)parents:存储父节点
# 数组:processed 记录处理过的数组
# the graph
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] = 1

graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5

# the costs table
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity

# the parents table
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

processed = []

# 两个重要的点:1)节点 lowest_cost_node;2)节点成本 lowest_cost
def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:  # 遍历所有节点
        cost = costs[node]
        if cost < lowest_cost and node not in processed:  #如果当前节点开销更低且未处理过
            lowest_cost = costs
            lowest_cost_node = node
    return lowest_cost_node

# 三个重要的点 :1)node(开销最小的节点);2)该节点的邻居 neighbours.keys();3)成本。cost+neighbours[n]。经该节点,到邻居的成本
node = find_lowest_cost_node(costs)    # 在未处理节点中找出开销最小的节点
while node is not None:               # 这个while循环在所有节点都被处理过后结束
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():         # 遍历当前节点的所有邻居
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost:        # 如果当前节点前往该邻居更近
            costs[n] = new_cost        # 就更新该邻居的开销
            parents[n] = node          # 同时将该邻居的父节点设置为当前节点
    processed.append(node)             # 将当前节点标记为处理过
    node = find_lowest_cost_node(costs)  # 找出接下来要处理的节点,并循环

总结
 广度优先搜索用于在非加权图中查找最短路径。
 狄克斯特拉算法用于在加权图中查找最短路径。
 仅当权重为正时狄克斯特拉算法才管用。
 如果图中包含负权边,请使用贝尔曼福德算法。

转载于:https://my.oschina.net/workhardforward/blog/1842279

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值