python中的图结构——图的遍历

图的遍历

  • python中图的建立
    • 顶点表结点 VertexNode
    • 边表结点 EdgeNode
    • 利用邻接表存储图的结构AdGraph
  • 深度优先搜索遍历
    • 介绍
    • 代码
  • 广度优先搜索遍历
    • 介绍
    • 代码
  • 运行结果示例
  • 两种搜索的对比

python中图的建立

这一部分完全参考:https://blog.csdn.net/LSGO_MYP/article/details/91435589
用临接表的形式储存图
python中的图结构——图的遍历_第1张图片

顶点表结点 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

运行结果示例

python中的图结构——图的遍历_第2张图片

两种搜索的对比

深度优先搜索用栈(stack)来实现,整个过程可以想象成一个倒立的树形:
1、把根节点压入栈中。
2、每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。

广度优先搜索使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。

你可能感兴趣的:(数据结构)