我对数据结构仍然不是很了解,但我有这个家庭作业要求我测试一个树状结构是否是圆形的。也就是说,以某种形式,节点的左右指针最终指向较早的节点。
我一直试图想出几个小时的递归函数,但我似乎无法得到它。我也没有太多的工作要展示它。 有人可以给我一些关于如何做到这一点的想法吗? 我们使用的语言是C。
感谢。
答案 0 :(得分:2)
通常,最好的方法是使用深度优先搜索(DFS)。从根节点开始,将其标记为“已访问”,然后开始按照指针进行操作。在您到达的每个新节点上,将其标记为“已访问”。如果你达到了死胡同,请备份并尝试另一条路径。
如果您按照指针并到达已标记为已访问过的节点,那么您就有了一个循环。
如何递归地执行:
struct node {
struct node *left;
struct node *right;
bool visited;
};
bool check_tree(struct node *cur)
{
if (cur == NULL)
return true;
if (cur->visited)
return false; // uh oh. We've been here...
cur->visited = true;
return check_tree(cur->left)
&& check_tree(cur->right);
}
if (check_tree(&root))
printf("No self-references here.\n");
(警告:代码可能有错误)
答案 1 :(得分:1)
您需要查看Topological Sort算法。
您将注意到维基百科链接上提供的伪代码,在排序过程中,您将了解任何循环引用。
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
insert n into L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
**output error message (graph has at least one cycle)**
else
output message (proposed topologically sorted order: L)
编辑:
这个答案是在作者表示他基本上有一个双链表结构之前发布的。我发布它不是因为我认为它在所有情况下都是最有效的答案,但是由于我们缺乏关于他的图表的信息(除了它作为“树”的描述),这个答案应该处理大多数情况。
答案 2 :(得分:1)
Floyd的'Tortoise& Hare'算法应该非常优雅地解决这个问题。请看这里:http://en.wikipedia.org/wiki/Cycle_detection
它非常适合列表,但也可以适用于像树一样走树。