Skip to content

Commit 0dbf6f7

Browse files
committed
更新了联通分量,环的检测,单源路径,二部图的检测(还存在bug)
1 parent 2419c1f commit 0dbf6f7

File tree

10 files changed

+713
-8
lines changed

10 files changed

+713
-8
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""
2+
@author: Alex
3+
4+
@file: BiPartitionDetection.py
5+
@time: 2019/10/22 17:50
6+
"""
7+
class BiPartitionDetection:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
self.__isBiPartite = True
14+
with open(filename) as f:
15+
line_num = 0 # 第一行是顶点数和边数
16+
for line in f:
17+
if line_num == 0:
18+
v, e = line.strip().split()
19+
self.V = int(v)
20+
self.E = int(e)
21+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
22+
else:
23+
# 读取边 写入邻接表
24+
v1, v2 = line.strip().split()
25+
# 转化为整数
26+
v1 = int(v1)
27+
v2 = int(v2)
28+
self.adj[v1].append(v2)
29+
self.adj[v2].append(v1)
30+
line_num += 1
31+
32+
def get_graph_information(self):
33+
"""
34+
打印图的邻接表
35+
:return:
36+
"""
37+
print("V={}, E={}".format(self.V, self.E))
38+
for i, v in enumerate(self.adj):
39+
print("{} : {}".format(i, v))
40+
41+
def validateVertex(self, v):
42+
"""
43+
验证顶点取值
44+
:param v:
45+
:return:
46+
"""
47+
if v<0 or v>=self.V:
48+
raise ValueError("v值超出范围")
49+
50+
51+
def graphDFS(self):
52+
visited = [False for i in range(self.V)]
53+
colors = [-1 for i in range(self.V)]
54+
55+
def dfs(v, color):
56+
# 标记v顶点已经遍历过了
57+
visited[v] = True
58+
for w in self.adj[v]:
59+
if visited[w] == False:
60+
if dfs(w, 1-color) == False:
61+
return False
62+
elif colors[w] == colors[v]:
63+
return False
64+
65+
# 顾及到有多个联通分量,对每个顶点都做DFS
66+
for i in range(self.V):
67+
if visited[i] == False:
68+
if dfs(i, 0) == False:
69+
self.__isBiPartite = False
70+
break
71+
def isBiPartite(self):
72+
return self.__isBiPartite
73+
74+
75+
76+
if __name__ == '__main__':
77+
BPD = BiPartitionDetection("../g.txt")
78+
BPD.get_graph_information()
79+
print(BPD.graphDFS())
80+
print(BPD.isBiPartite())

DFS_Application/CC.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
"""
2+
@author: Alex
3+
4+
@file: CC.py
5+
@time: 2019/10/20 19:12
6+
"""
7+
class CC:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
self.__cccount = 0 # 联通分量
14+
self.__visited = None
15+
16+
with open(filename) as f:
17+
line_num = 0 # 第一行是顶点数和边数
18+
for line in f:
19+
if line_num == 0:
20+
v, e = line.strip().split()
21+
self.V = int(v)
22+
self.E = int(e)
23+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
24+
else:
25+
# 读取边 写入邻接表
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1].append(v2)
31+
self.adj[v2].append(v1)
32+
line_num += 1
33+
34+
def get_graph_information(self):
35+
"""
36+
打印图的邻接表
37+
:return:
38+
"""
39+
print("V={}, E={}".format(self.V, self.E))
40+
for i, v in enumerate(self.adj):
41+
print("{} : {}".format(i, v))
42+
43+
def validateVertex(self, v):
44+
"""
45+
验证顶点取值
46+
:param v:
47+
:return:
48+
"""
49+
if v<0 or v>=self.V:
50+
raise ValueError("v值超出范围")
51+
52+
def hasEdge(self, v, w):
53+
"""
54+
判断两个顶点是否存在
55+
:param v: 第一个顶点
56+
:param w: 第二个顶点
57+
:return: true or false
58+
"""
59+
self.validateVertex(v)
60+
self.validateVertex(w)
61+
return w in self.adj[v]
62+
63+
def degree(self, v):
64+
"""
65+
求某个顶点的度
66+
:param v:
67+
:return:
68+
"""
69+
self.validateVertex(v)
70+
return len(self.adj[v])
71+
72+
73+
def graphDFS(self):
74+
visited = [-1 for i in range(self.V)]
75+
cccount = 0 # 联通分量
76+
77+
def dfs(v, ccid):
78+
# 标记v顶点已经遍历过了
79+
visited[v] = ccid
80+
# 添加
81+
for w in self.adj[v]:
82+
if visited[w] == -1:
83+
dfs(w, ccid)
84+
# 此刻对某个顶点的邻点已经遍历结束
85+
86+
# 顾及到有多个联通分量,对每个顶点都做DFS
87+
for i in range(self.V):
88+
if visited[i] == -1:
89+
dfs(i, cccount)
90+
cccount += 1
91+
self.__cccount = cccount
92+
self.__visited = visited
93+
94+
95+
def get_cccount(self):
96+
"""
97+
获取该图的联通分量大小
98+
:return:
99+
"""
100+
return self.__cccount
101+
102+
def get_visited(self):
103+
"""
104+
获取该图的联通分量列表
105+
:return:
106+
"""
107+
return self.__visited
108+
109+
def isConnected(self, v, w):
110+
"""
111+
查看两个顶点是否在一个联通分量中
112+
:param v:
113+
:param w:
114+
:return:
115+
"""
116+
self.validateVertex(v)
117+
self.validateVertex(w)
118+
return self.__visited[v] == self.__visited[w]
119+
120+
def components(self):
121+
# 为每一个联通分量开辟空间
122+
res = [[] for i in range(self.__cccount)]
123+
for v in range(self.V): # 遍历每一个顶点
124+
# 将相同联通分量的顶点放入同一个数组中, visited[0]=visited[1]=0, 则将0,1顶点放入索引为0的数组中
125+
res[self.__visited[v]].append(v)
126+
for i, row in enumerate(res):
127+
print("联通分量{}:{}".format(i, row))
128+
129+
130+
if __name__ == '__main__':
131+
adjl = CC("../g_unconnected.txt")
132+
adjl.get_graph_information()
133+
print(adjl.graphDFS())
134+
print(adjl.get_cccount())
135+
print(adjl.get_visited())
136+
print(adjl.isConnected(0, 4))
137+
adjl.components()

DFS_Application/CycleDetection.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"""
2+
@author: Alex
3+
4+
@file: CycleDetection.py
5+
@time: 2019/10/22 15:48
6+
"""
7+
# 环检测(邻接矩阵)
8+
class CycleDetection:
9+
10+
def __init__(self, filename):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
14+
self.__hasCycle = None
15+
with open(filename) as f:
16+
line_num = 0 # 第一行是顶点数和边数
17+
for line in f:
18+
if line_num == 0:
19+
v, e = line.strip().split()
20+
self.V = int(v)
21+
self.E = int(e)
22+
# self.adj = [[0] * self.V] * self.V # 该创建方式不正确 修改任何一个元素都会改变整个列表
23+
self.adj = [([0] * self.V) for i in range(self.V)] # 创建二维数组即邻接矩阵
24+
else:
25+
# 读取边 写入邻接矩阵
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1][v2] = 1
31+
self.adj[v2][v1] = 1
32+
line_num += 1
33+
34+
# 初始化图时,进行深度优先搜索
35+
self.graphDFS()
36+
37+
def get_graph_information(self):
38+
"""
39+
打印图的邻接矩阵
40+
:return:
41+
"""
42+
print("V={}, E={}".format(self.V, self.E))
43+
print(self.adj)
44+
45+
def validateVertex(self, v):
46+
"""
47+
验证顶点取值
48+
:param v:
49+
:return:
50+
"""
51+
if v<0 or v>=self.V:
52+
raise ValueError("v值超出范围")
53+
54+
55+
def graphDFS(self):
56+
visited = [False for i in range(self.V)]
57+
58+
def dfs(v, parent):
59+
# 标记v顶点已经遍历过了
60+
visited[v] = True
61+
for w in self.adj[v]:
62+
if visited[w] == False:
63+
dfs(w, v)
64+
else:
65+
if w != parent:
66+
return True
67+
return False
68+
69+
for i in range(self.V):
70+
if visited[i] == False:
71+
if dfs(i, i):
72+
self.__hasCycle = True
73+
break
74+
75+
def hasCycle(self):
76+
if self.__hasCycle:
77+
print("该图存在环")
78+
else:
79+
print("该图没有环")
80+
81+
# 环检测(邻接表)
82+
class CycleDetection_v2:
83+
84+
def __init__(self, filename):
85+
self.V = 0 # 顶点数
86+
self.E = 0 # 边数
87+
self.adj = None
88+
self.__hasCycle = None
89+
with open(filename) as f:
90+
line_num = 0 # 第一行是顶点数和边数
91+
for line in f:
92+
if line_num == 0:
93+
v, e = line.strip().split()
94+
self.V = int(v)
95+
self.E = int(e)
96+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
97+
else:
98+
# 读取边 写入邻接表
99+
v1, v2 = line.strip().split()
100+
# 转化为整数
101+
v1 = int(v1)
102+
v2 = int(v2)
103+
self.adj[v1].append(v2)
104+
self.adj[v2].append(v1)
105+
line_num += 1
106+
107+
# 初始化图时,进行深度优先搜索
108+
self.graphDFS()
109+
110+
def get_graph_information(self):
111+
"""
112+
打印图的邻接矩阵
113+
:return:
114+
"""
115+
print("V={}, E={}".format(self.V, self.E))
116+
for i, v in enumerate(self.adj):
117+
print("{} : {}".format(i, v))
118+
119+
def validateVertex(self, v):
120+
"""
121+
验证顶点取值
122+
:param v:
123+
:return:
124+
"""
125+
if v<0 or v>=self.V:
126+
raise ValueError("v值超出范围")
127+
128+
129+
def graphDFS(self):
130+
visited = [False for i in range(self.V)]
131+
132+
def dfs(v, parent):
133+
# 标记v顶点已经遍历过了
134+
visited[v] = True
135+
for w in self.adj[v]:
136+
if visited[w] == False:
137+
# if dfs(w, v):
138+
# return True
139+
dfs(w, v)
140+
print(v, w, parent)
141+
else:
142+
if w != parent:
143+
print(v, w, parent)
144+
return True
145+
return False
146+
147+
# 顾及到有多个联通分量,对每个顶点都做DFS
148+
for i in range(self.V):
149+
if visited[i] == False:
150+
if dfs(i, i):
151+
self.__hasCycle = True
152+
break
153+
154+
def hasCycle(self):
155+
if self.__hasCycle:
156+
print("该图存在环")
157+
else:
158+
print("该图没有环")
159+
160+
if __name__ == '__main__':
161+
CD = CycleDetection("../g_cycle.txt")
162+
CD.get_graph_information()
163+
CD.hasCycle()
164+
print("=======第二种========")
165+
CD2 = CycleDetection_v2("../g.txt")
166+
CD2.get_graph_information()
167+
CD2.hasCycle()

0 commit comments

Comments
 (0)