这条线有什么作用?
node.next = self.graph[src]
例如:[1:2]在这里我知道如何将 2 作为节点,然后使索引 1 等于它,但是如果我也有[1:3],如何将 3 加到 2 怎么办?
这是邻接列表实现的完整代码
class AdjNode:
def __init__(self, data):
self.vertex = data
self.next = None
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.graph = [None] * self.vertices
def add_edge(self, src, dest):
node = AdjNode(dest)
#==================================================
node.next = self.graph[src]
#==================================================
self.graph[src] = node
def print_graph(self):
for i in range(self.vertices):
print("Adjacency list of vertex {}n {}".format(i,i), end="")
temp = self.graph[i]
while temp:
print(" -> {}".format(temp.vertex), end="")
temp = temp.next
print(" n")
V = 5
graph = Graph(V)
graph.add_edge(0, 1)
graph.add_edge(0, 4)
graph.add_edge(1, 2)
graph.add_edge(1, 3)
graph.add_edge(1, 4)
graph.add_edge(2, 3)
graph.add_edge(3, 4)
graph.print_graph()
输出
Adjacency list of vertex 0
0 -> 4 -> 1
Adjacency list of vertex 1
1 -> 4 -> 3 -> 2
Adjacency list of vertex 2
2 -> 3
Adjacency list of vertex 3
3 -> 4
Adjacency list of vertex 4
4
例如:[1:2] 在这里我知道如何将 2 作为节点,然后使索引 1 等于它,但是如果我也有 [1:3],如何将 3 加到 2 怎么办?
可视化该过程可能会有所帮助。因此,假设有四个节点,编号为 0、1、2 和 3,那么我们self.graph
初始化如下(框由索引访问):
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: None │ 2: None │ 3: None │
└─────────┴─────────┴─────────┴─────────┘
假设graph.add_edge(1, 2)
将是该图上的第一个操作,那么src
是 1,dst
是 2。node = AdjNode(dest)
的第一个语句将带来此状态:
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: None │ 2: None │ 3: None │
└─────────┴─────────┴─────────┴─────────┘
┌────────────┐
node → │ vertex: 2 │
│ next: None │
└────────────┘
下一个语句node.next = self.graph[src]
现在没有多大作用,因为它只是将None
分配给已经存在的node.next
。最后,graph[src] = node
确实做了一个重要的链接:
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: ─┐ │ 2: None │ 3: None │
└─────────┴─────│───┴─────────┴─────────┘
│
│
│
▼
┌────────────┐
node → │ vertex: 2 │
│ next: None │
└────────────┘
然后函数返回,node
不再是范围内的名称。
现在,让我们看看graph.add_edge(1, 3)
的作用。所以src
又是 1,但dst
是 3。通常的节点是使用node = AdjNode(dest)
创建,给出此状态(新节点的新node
名称):
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: ─┐ │ 2: None │ 3: None │
└─────────┴─────│───┴─────────┴─────────┘
node │
↓ │
┌────────────┐ │
│ vertex: 3 │ │
│ next: None │ │
└────────────┘ │
▼
┌────────────┐
│ vertex: 2 │
│ next: None │
└────────────┘
现在发生了"神奇"任务:node.next = self.graph[src]
.这会将self.graph[src]
的引用复制到node.next
中。在图像中,这意味着箭头被复制,以便它们指向相同的事物:
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: ─┐ │ 2: None │ 3: None │
└─────────┴─────│───┴─────────┴─────────┘
node │
↓ │
┌────────────┐ │
│ vertex: 3 │ │
│ next: ─┐ │ │
└────────│───┘ │
▼ ▼
┌────────────┐
│ vertex: 2 │
│ next: None │
└────────────┘
最后,我们执行graph[src] = node
:
self.graph
↓
┌─────────┬─────────┬─────────┬─────────┐
│ 0: None │ 1: ─┐ │ 2: None │ 3: None │
└─────────┴─────│───┴─────────┴─────────┘
node │
↓ ▼
┌────────────┐
│ vertex: 3 │
│ next: ─┐ │
└────────│───┘
▼
┌────────────┐
│ vertex: 2 │
│ next: None │
└────────────┘
因此,在所有这些之后,后面的目标节点在已经位于self.graph[src]
的列表中的节点之前被前缀为链表。
我希望这能澄清它。