Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c0f129d

Browse files
添加DFS和DFS的应用
1 parent 0dbf6f7 commit c0f129d

File tree

8 files changed

+551
-2
lines changed

8 files changed

+551
-2
lines changed

‎DFS_Application/CycleDetection.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,6 @@ def hasCycle(self):
162162
CD.get_graph_information()
163163
CD.hasCycle()
164164
print("=======第二种========")
165-
CD2 = CycleDetection_v2("../g.txt")
165+
CD2 = CycleDetection_v2("../g_cycle.txt")
166166
CD2.get_graph_information()
167167
CD2.hasCycle()

‎Graph/stackDFS.py‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: stackDFS.py
5+
@time: 2019年10月24日 20:09
6+
"""
7+
8+
class Node(object):
9+
def __init__(self, data, next=None):
10+
self.data = data
11+
self.next = next
12+
13+
class Stack(object):
14+
15+
def __init__(self, top = None):
16+
self.top = top
17+
18+
def push(self,data):
19+
#创建新的节点放到栈顶
20+
self.top = Node(data, self.top)
21+
22+
def pop(self):
23+
#拿出栈顶元素,原来的栈发生改变
24+
if self.top is None:
25+
return None
26+
data = self.top.data
27+
self.top = self.top.next
28+
return data
29+
30+
def peek(self):
31+
#查看栈顶元素,原来的栈不变
32+
return self.top.data if self.top is not None else None
33+
34+
def isEmpty(self):
35+
return self.peek() is None
36+
37+
38+
39+
class stackDFS:
40+
41+
def __init__(self, filename):
42+
self.V = 0 # 顶点数
43+
self.E = 0 # 边数
44+
self.adj = None
45+
self.__pre = [] # 深度遍历
46+
with open(filename) as f:
47+
line_num = 0 # 第一行是顶点数和边数
48+
for line in f:
49+
if line_num == 0:
50+
v, e = line.strip().split()
51+
self.V = int(v)
52+
self.E = int(e)
53+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
54+
else:
55+
# 读取边 写入邻接表
56+
v1, v2 = line.strip().split()
57+
# 转化为整数
58+
v1 = int(v1)
59+
v2 = int(v2)
60+
self.adj[v1].append(v2)
61+
self.adj[v2].append(v1)
62+
line_num += 1
63+
64+
self.__visited = [False for i in range(self.V)]
65+
# 对每个顶点进行遍历
66+
for i in range(self.V):
67+
if self.__visited[i] == False:
68+
self.graph_stack_DFS(i)
69+
70+
71+
def graph_stack_DFS(self, v):
72+
stack = Stack()
73+
74+
75+
# 将v压入栈中,标记v顶点已经访问过
76+
stack.push(v)
77+
self.__visited[v] = True
78+
79+
# 循环遍历取出栈中的元素
80+
while stack.isEmpty() == False:
81+
82+
# 从栈顶取出元素
83+
cur = stack.pop()
84+
self.__pre.append(cur)
85+
86+
# 对cur的相邻的未遍历过的顶点,分别将它们压入栈中,并做标记
87+
for w in self.adj[cur]:
88+
# 查看cur的相邻顶点w是否被遍历过了
89+
if self.__visited[w] == False:
90+
# 此时说明未被遍历过,将w压入栈中
91+
stack.push(w)
92+
# 维护visited数组,标记w已经被访问过
93+
self.__visited[w] = True
94+
95+
def get_dfs_order(self):
96+
print("深度优先遍历(非递归实现):{}".format(self.__pre))
97+
98+
if __name__ == '__main__':
99+
SDFS = stackDFS("../g_ssp.txt")
100+
SDFS.get_dfs_order()

‎Graph_BFS/BFS.py‎

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: BFS.py
5+
@time: 2019年10月24日 15:51
6+
"""
7+
import queue
8+
class GraphBFS:
9+
10+
def __init__(self, filename):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
14+
self.__cccount = 0 # 联通分量
15+
self.__order = [] # 广度优先遍历
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+
self.graphBFS()
34+
35+
def get_graph_information(self):
36+
"""
37+
打印图的邻接表
38+
:return:
39+
"""
40+
print("V={}, E={}".format(self.V, self.E))
41+
for i, v in enumerate(self.adj):
42+
print("{} : {}".format(i, v))
43+
44+
def validateVertex(self, v):
45+
"""
46+
验证顶点取值
47+
:param v:
48+
:return:
49+
"""
50+
if v<0 or v>=self.V:
51+
raise ValueError("v值超出范围")
52+
53+
def hasEdge(self, v, w):
54+
"""
55+
判断两个顶点是否存在
56+
:param v: 第一个顶点
57+
:param w: 第二个顶点
58+
:return: true or false
59+
"""
60+
self.validateVertex(v)
61+
self.validateVertex(w)
62+
return w in self.adj[v]
63+
64+
def degree(self, v):
65+
"""
66+
求某个顶点的度
67+
:param v:
68+
:return:
69+
"""
70+
self.validateVertex(v)
71+
return len(self.adj[v])
72+
73+
74+
def graphBFS(self):
75+
visited = [False for i in range(self.V)]
76+
order = []
77+
78+
def bfs(v):
79+
# 使用队列来存放经过结点
80+
que = queue.Queue(self.V)
81+
# 经过顶点v时,将v放进队列中
82+
que.put(v)
83+
visited[v] = True
84+
# 队列为空时,即在某个联通分量已经遍历完毕
85+
while que.empty() == False:
86+
# 取出v 并做标记将v放入order 后面开始对v的邻点遍历
87+
v = que.get()
88+
order.append(v)
89+
90+
for w in self.adj[v]:
91+
if visited[w] == False:
92+
que.put(w)
93+
visited[w] = True
94+
95+
for i in range(self.V):
96+
if visited[i] == False:
97+
bfs(i)
98+
self.__order = order
99+
100+
def get_cccount(self):
101+
"""
102+
获取该图的联通分量
103+
:return:
104+
"""
105+
return self.__cccount
106+
107+
def get_BFSorder(self):
108+
"""
109+
获取该图的广度优先搜素
110+
:return:
111+
"""
112+
print("广度优先搜索:{}".format(self.__order))
113+
114+
if __name__ == '__main__':
115+
bfs = GraphBFS("../g.txt")
116+
bfs.get_graph_information()
117+
bfs.get_BFSorder()

‎Graph_BFS/CC.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: CC.py
5+
@time: 2019年10月24日 20:42
6+
"""
7+
import queue
8+
# 联通分量
9+
class CC:
10+
def __init__(self, filename):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
14+
self.__cccount = 0 # 联通分量
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 = [[] for i in range(self.V)] # 创建二维数组即邻接表
23+
else:
24+
# 读取边 写入邻接表
25+
v1, v2 = line.strip().split()
26+
# 转化为整数
27+
v1 = int(v1)
28+
v2 = int(v2)
29+
self.adj[v1].append(v2)
30+
self.adj[v2].append(v1)
31+
line_num += 1
32+
33+
self.__visited = [-1 for i in range(self.V)]
34+
# 对每个顶点进行遍历
35+
for i in range(self.V):
36+
if self.__visited[i] == -1:
37+
self.bfs(i, self.__cccount)
38+
self.__cccount += 1
39+
40+
# 非递归
41+
def bfs(self, s, ccid):
42+
que = queue.Queue(self.V)
43+
# 将经过的点放入队列中
44+
que.put(s)
45+
self.__visited[s] = ccid
46+
# 队列为空的时候说明此时已经遍历结束
47+
while que.empty() == False:
48+
# 取出s的相邻顶点v,并对v的相邻顶点w遍历,将遍历过的顶点在visited数组中做标记
49+
v = que.get()
50+
for w in self.adj[v]:
51+
if self.__visited[w] == -1:
52+
que.put(w)
53+
self.__visited[w] = ccid
54+
55+
def get_ccount(self):
56+
print("联通分量大小为:{}".format(self.__cccount))
57+
58+
def get_components(self):
59+
res = [[] for i in range(self.__cccount)]
60+
61+
for i in range(self.V):
62+
res[self.__visited[i]].append(i)
63+
print("各联通分量为:{}".format(res))
64+
65+
if __name__ == '__main__':
66+
cc = CC("../g_ssp.txt")
67+
cc.get_ccount()
68+
cc.get_components()

‎Graph_BFS/CycleDetection.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: CycleDetection.py
5+
@time: 2019年10月24日 21:18
6+
"""
7+
import queue
8+
class CycleDetection:
9+
10+
def __init__(self, filename):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
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+
self.visited = [False for i in range(self.V)]
33+
self.pre = [-1 for i in range(self.V)] # 记录每一个结点的父亲结点即上一个结点
34+
self.hasCycle = False
35+
36+
# 对每一个结点都进行遍历
37+
for v in range(self.V):
38+
# 若该结点为未被访问过,即二部图的情况
39+
if self.visited[v] == False:
40+
if self.bfs(v) == True:
41+
self.hasCycle = True
42+
break
43+
44+
45+
def bfs(self, s):
46+
que = queue.Queue(self.V)
47+
que.put(s)
48+
self.visited[s] = True
49+
self.pre[s] = s
50+
51+
while que.empty() == False:
52+
v = que.get()
53+
54+
# 将v的每一个未访问的相邻结点w都压入队列
55+
for w in self.adj[v]:
56+
if self.visited[w] == False:
57+
que.put(w)
58+
self.visited[w] = True
59+
self.pre[w] = v
60+
elif self.pre[v] != w:
61+
# 此处是检测环的关键,如果w被访问过了,要检测w是不是上一个结点v,如果不是,则有环
62+
return True
63+
64+
def get_hasCycle(self):
65+
return self.hasCycle
66+
if __name__ == '__main__':
67+
cd = CycleDetection("../g_cycle.txt")
68+
print(cd.get_hasCycle())

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /