图的遍历
python中图的建立
顶点表结点 VertexNode
边表结点 EdgeNode
利用邻接表存储图的结构AdGraph
深度优先搜索遍历
介绍
代码
广度优先搜索遍历
介绍
代码
运行结果示例
两种搜索的对比
python中图的建立
这一部分完全参考:https://blog.csdn.net/LSGO_MYP/article/details/91435589
用临接表的形式储存图
顶点表结点 VertexNode
#!/usr/bin/python
# -*- coding: UTF-8 -*-
lass VertexNode(object): #顶点表节点
def __init__(self,vertexname,visited=False,p=None):
self.vertexName =vertexname #节点名字
self.Visited=visited #此节点是否被访问过
self.firstNode = p #指向所连接的边表节点的指针(EdgeNode)
边表结点 EdgeNode
class EdgeNode(object): #边表节点
def __init__(self,index,weight,p=None):
self.Index =index #尾节点在边表中对应序号
self.Weight=weight #边的权值
self.Next = p #链接同一头节点的下一条边
利用邻接表存储图的结构AdGraph
class Adgraph(object):
def __init__(self,vcount=0):
self.vertexList = [] #用list链接边表
self.vertexCount = vcount
def initlist(self,data): #初始化
for da in data:
A=VertexNode(da)
self.vertexList.append(A)
self.vertexCount=len(data)
def GetIndex(self,data): #获取指定名称的节点的序号
for i in range(self.vertexCount):
temp=self.vertexList[i].vertexName
if (temp!=None)and(data == temp):
return i
return -1
def AddEdge(self,startNode,endNode,weight): #添加边的信息
i=self.GetIndex(startNode)
j=self.GetIndex(endNode)
if i==-1 or j==-1:
print("不存在该边")
else:
weight=float(weight)
temp=self.vertexList[i].firstNode
if temp==None: #若边表下无顶点信息
self.vertexList[i].firstNode=EdgeNode(j,weight)
else: #若边表下已有顶点信息
while(temp.Next!=None):
temp=temp.Next
temp.Next=EdgeNode(j,weight)
深度优先搜索遍历
介绍
简单来说,就是从起点顶点沿着边表出发,发现有没访问的点,就沿着这个顶点的边表往前走,把走过的点设为已访问,走不了就退回上一个访问的点继续走。
代码
def DFS(self,i): #深度优先搜索递归
self.vertexList[i].Visited=True
result=self.vertexList[i].vertexName+'\n'
p=self.vertexList[i].firstNode
while(p!=None):
if self.vertexList[p.Index].Visited==True:
p=p.Next
else:
result+=self.DFS(p.Index)
return result
def DFStravel(self,start): #深度优先搜索入口
i=self.GetIndex(start)
if i!=-1:
for j in range(self.vertexCount):
self.vertexList[j].Visited=False
DFSresult=self.DFS(i)
return DFSresult
广度优先搜索遍历
介绍
简单的说,广度优先搜索是从根节点开始,先把这一个节点加入一个先进先出的队列,然后沿着此节点的边表访问其链接的没被访问的节点并加入队列,然后此节点退队,再取队首元素边表逐一访问,如果发现队列为空,则演算终止。
代码
def BFStravel(self,start): #广度优先搜索
BFSresult=''
i=self.GetIndex(start)
if i!=-1:
for j in range(self.vertexCount):
self.vertexList[j].Visited=False
self.vertexList[i].Visited=True
BFSresult+=self.vertexList[i].vertexName+'\n'
GList=[i] #记录遍历顺序(用list代替队列)
while(GList!=[]):
j=GList.pop(0)
p=self.vertexList[j].firstNode
while p!=None:
k=p.Index
if (self.vertexList[k].Visited==False):
self.vertexList[k].Visited=True
BFSresult+=self.vertexList[k].vertexName+'\n'
GList.append(p.Index)
p=p.Next
return BFSresult
运行结果示例
两种搜索的对比
深度优先搜索用栈(stack)来实现,整个过程可以想象成一个倒立的树形:
1、把根节点压入栈中。
2、每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。
广度优先搜索使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。