图 - 邻接列表作为链表求解



这条线有什么作用?

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]的列表中的节点之前被前缀为链表。

我希望这能澄清它。

相关内容

  • 没有找到相关文章

最新更新