1. Definitions
Vertex: 角, or Node.
Edge: 边, or Edge.
Weight: 权重,the cost to go from one node to another, following an edge.
2.adjacent matrix 邻接矩阵
使用一个二维数组来表达一个图:
图中行跟列都表示节点,第v0行第v1列:表示从v0到v1有一条通道,其权重是5。
但是矩阵是一个疏松的矩阵,浪费了大量的空间,所以我们一般只用领接矩阵表示一个小的graph.
3. adjacent list 邻接列表
邻接列表的使用是存储一个list,该list存储了图中的每一条边,并且每一个边存储了一个它连接的边的list.
我们也可以使用一个list和一个dict来实现一个邻接列表,其中list保存所有的节点,同时dict来保存该节点连接的节点。其中key为到达的节点,val保存weight
[ {'v1' : 5, 'v5' : 2}, {'v2' : 4 }, { 'v3' : 9}, {'v4' : 7, 'v5' : 3},{'v0' : 1}, {'v2':1, 'v4':8}]
4.用队列Queue来实现BFS(广度优先搜索)
广度优先其实就是一个queue
首先
1.queue 使用Queue来保存将要访问的元素。
2.list 用一个list来保存访问过的节点。
假设我们需要寻找最短路径。
1. 先将开始节点入队列 [start]。
2. while 队列不为空:出栈,如果是结束节点则结束。如果该节点没有访问过,则放入访问队列,然后将该节点的所有子节点入栈。如果该节点访问过,pass。
以leetcode 127题 word ladder 为例子
class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
d = {}
for word in wordList:
for i in range(len(word)):
temp = word[:i] + "*" + word[i+1:]
if d.get(temp)!= None:
d[temp].append(word)
else:
d[temp] = [word]
queue = [[beginWord, 1]]
visited = []
while len(queue) > 0: #当queue不为零
thisNode = queue[0]
queue.pop(0) #pop出来
if thisNode[0] == endWord: #如果到终点,则返回走了多少步
return thisNode[1]
if thisNode[0] not in visited:#如果不是终点,那看是不是已经走过
word, step = thisNode[0], thisNode[1]
visited.append(word)
for i in range(len(word)):
proto = word[:i] + "*" + word[i+1:]
candidates = []
if d.get(proto) != None:
candidates = d[proto]
for a in candidates:
if a !=word:
queue.append([a, step+1]) #将所有候选加入队列中
return 0
5. DFS深度优先搜索
递归来找,直到找到最后!
其实就是用stack来放置下次需要访问的元素
6. 最短路径问题 Dijkstra算法
参考:https://www.jianshu.com/p/ff6db00ad866
使用S存储已经确定最短距离的点,U内存储还没被确定的。
#suppose A is the starting point
IndexList = ['A', 'B', 'C', 'D', 'E']
graph = [[0,4,100,2,100],[4,0,4,1,100],[100,4,0,1,3],[2,1,1,0,7],[100,100,3,7,0]]
S = []
U = []
for i in range(len(IndexList)):
U.append([IndexList[i],graph[i][0]])
while len(U) > 0:
#加入最小值
U.sort(key = lambda x : x[1])
S.append(U[0])
U.pop(0)
#更新U
for i in range(len(U)):
x = IndexList.index(U[i][0])
for j in range(len(S)):
y = IndexList.index(S[j][0])
if graph[x][y] + S[j][1] < U[i][1]:
U[i][1] = graph[x][y] + S[j][1]
print(S)
#书上的最短路径代码:
使用一个list,每行代表到当前路径的最短路径
使用bfs来从初始点行走,每次更新最短路径
leetcode 547