Короче говоря: Вы изменяете размер defaultdict
, получая доступ к несуществующему члену .
Вы делаете следующее:
L oop сверх self.adj_list
, что (несмотря на название) является defaultdict
Вызовом Topological_Sort_Util
с узлом из self.adj_list
(до сих пор) так хорошо)
L oop над детьми в self.adj_list[input_node]
Вызовите Topological_Sort_Util
рекурсивно с детьми узла
Последний шаг, где вещи go не так в вашем примере. Узел 1 имеет узел 3 как единственный дочерний элемент, но вы никогда не добавите узел 3 к adj_list
. Поскольку adj_list
является defaultdict
, строка
for child in self.adj_list[input_node]:
добавит новый ключ для input_node
в adj_list
, если он еще не существует. Это изменяет размер словаря, и выдается исключение.
Это можно увидеть, напечатав adj_list
до и после вызова Topological_Sort_Util
:
defaultdict(<class 'list'>, {1: [3], 2: [1], 4: [2, 3]}) # before
defaultdict(<class 'list'>, {1: [3], 2: [1], 4: [2, 3], 3: []}) # after
. Вы можете исправьте это, убедившись, что дочерний узел существует в Insert_Node
:
def Insert_Node(self, u, v):
self.adj_list[u].append(v)
self.adj_list[v]
Другая проблема
Ваш атрибут visited
- это list
, который использует индексирование на основе 0, но вы начинаете нумерацию своих узлов с 1. Итак, когда вы делаете
self.visited[input_node] = True
, это не удастся для узла 4, потому что ваш list
имеет только размер 4 (последний индекс равен 3).
Так что вам либо нужно
- Конвертировать
visited
в диктовку с произвольными ключами, либо - Убедитесь, что
visited
достаточно большой, чтобы индексировать все ваши узлы или - Начать нумерацию узлов с 0