| 内容: 对具有n个结点的无向图,判断其能否被一笔画。 要求: 对给定n个结点的无向图,进行欧拉图和半欧拉图的判定,若是欧拉图或半欧拉图,则输出所有的欧拉(回)路。 |
所采用的数据结构:栈(通过python的列表类型pop来模拟)
所采用的的存储结构:字典(存放某一个结点的所有相邻的结点)、集合set(去重+检测是否走过该节点)
函数:
'''函数功能:完成邻接矩阵的初始化'''
'''函数功能:求可达性矩阵'''
'''函数功能:通过邻接矩阵获取到每一个节点的度数,在保证连通性的前提下,通过奇数度节点直接判别出欧拉路or欧拉回路'''
''' 函数功能:由邻接矩阵求出一个字典:每一个节点 映射 相邻节点 '''
''' 函数功能:通过dfs算法求出欧拉(回)路 '''
时间复杂度:O(n²)
实验思路:
- import numpy as np
- from random import randint
- '''函数功能:完成邻接矩阵的初始化'''
- def init():
- n,m=eval(input("请输入图的结点数和边数(逗号隔开):"))
- matrix = np.zeros((n, n), dtype=int) #图的邻接矩阵
- m_list=(input("请输入有关联关系的两个结点1,3(每一对中间用空格隔开):例如 1,5 1,6 在无向图中表示结点1和节点5、6是相互可达的\n")).split(' ')
- for i in m_list: #根据用户的输入,完成邻接矩阵的初始化
- matrix[eval(i[0])-1,eval(i[-1])-1]=1;
- matrix[eval(i[-1])-1, eval(i[0])-1] = 1; #无向图的邻接矩阵是对称的 减去1是为了与矩阵的下标对应
- return matrix,n
-
- '''函数功能:求可达性矩阵'''
- def GetReachableMatrix(A,n): #参数A:邻接矩阵 参数n:结点个数
- temp = np.array(A, dtype=int)
- C=np.zeros((n,n),dtype=int) #B是可达性矩阵
- for i in range(n):
- C+=temp
- temp=np.dot(temp,A)
- t=np.array(C,dtype=bool)
- B=np.array(t,dtype=int)
- return B
-
- '''函数功能:通过邻接矩阵获取到每一个节点的度数,在保证连通性的前提下,通过奇数度节点直接判别出欧拉路or欧拉回路'''
- def GetOddDegree(matrix,n):
- count=0 #表示奇数度的大小
- for i in range(n):
- sum=0
- for j in range(n):
- sum+=matrix[i][j]
- if sum%2 !=0:# 说明是奇数
- count+=1
- return count
-
- ''' 函数功能:由邻接矩阵求出一个字典:每一个节点 映射 相邻节点 '''
- def GetGraph(matrix,n):
- graph=dict() #生成一个空字典
- for i in range(n):
- graph["v"+str(i+1)]=list()#映射的对象是一个列表
- for j in range(n):
- if matrix[i][j]==1:
- #向列表中添加邻接节点
- graph["v"+str(i+1)].append("v"+str(j+1))
- return graph
-
- def DFS(graph,start): #参数 graph是邻接节点的一个字典 参数start是起始点
- stack=[] #当栈用
- seen=set() #创建一个集合,查重用(判断这条路是否已经走过)+记录路径的作用
- print("一笔画路径为:",end="")
- stack.append(start)
- seen.add(start)
- while (len(stack)>0):
- vertx=stack.pop() #默认是从栈顶取出
- node=graph[vertx]
- for i in node:
- if i not in seen:#确保之前没有走过该节点
- stack.append(i)
- seen.add(i)
- print(vertx+"->",end="")
- print("\b\b")
-
- if __name__=='__main__':
- matrix,Node=init() #initial info
- templateMatrix=np.ones((Node,Node),dtype=int) #连通性阵的可达性矩阵的模板 全是1 用于比较
- ReachhableMatrix=GetReachableMatrix(matrix,Node) #求可达性矩阵
- graph=GetGraph(matrix,Node) #得到每一个节点的邻接节点构成的字典dict
- r=randint(0,Node)
- print("邻接矩矩阵为:\n",matrix)
-
- if (templateMatrix==ReachhableMatrix).all():
- if GetOddDegree(matrix,Node)==0:#奇数度节点为0个,说明是欧拉图
- DFS(graph, "v"+str(Node))
- print("是欧拉图-->可以一笔画")
- elif GetOddDegree(matrix,Node):
- DFS(graph, "v"+str(Node))
- print("是半欧拉图-->可以一笔画")
- else:
- print("既不是欧拉路,也不是欧拉回路-->不能一笔画")
- else:
- print("非连通图,既不是半欧拉图,也不是欧拉图-->不能一笔画")
大一下还没有学dfs
推荐一个b站的相关资源,快速上手bfs和dfs(用python)