Я не знаю Ruby, но если у вас есть удобная реализация хеш-таблицы и связанного списка, я бы сделал это примерно так (в псевдокоде Java-ish):
Topic currentTopic = topic;
list.add(currentTopic);
hashtable.add(currentTopic);
while (list.empty() == false) {
for (Topic t : currentTopic.getSubtopics()) {
if (hashtable.contains(t) == false) {
list.add(t);
hashtable.add(t);
}
}
visit(currentTopic);
list.remove(currentTopic);
currentTopic = list.getFirst();
}
Главное здесь - сохранить список хеш-таблиц, чтобы вы могли легко убедиться, что вы никогда не посетите тему дважды. Кроме этого, это, по сути, реализация поиска в ширину . visit () делает все, что вам нужно для каждой отдельной темы.