如何在不使用堆栈的情况下在 O(n)中非递归地遍历线程化二叉树(只允许为临时变量使用常量额外空间,所以我们可以不要为树中的每个节点添加访问标志。我花了很多时间思考它,但在我看来似乎并不可行除非我们将遍历具有树数据的内存位置。假设我们使用多个数组表示来实现指针,那么我们可以在O(n)中遍历树,是否还有人想到其他东西?
注意这是不作业,只是为了节省一些键盘敲击的能量来写关于家庭作业的评论!
答案 0 :(得分:5)
假设我们在C中有以下线程树表示:
typedef struct threaded_binary_tree {
int value;
// Flag that tells whether right points to a right child or to a next
// node in inorder.
bool right_is_child;
struct threaded_binary_tree *left, *right;
} threaded_binary_tree;
然后,在O(1)
内存中遍历它可能如下所示:
void inorder(threaded_binary_tree *node)
{
threaded_binary_tree *prev = NULL;
// Ignore empty trees
if (node == NULL)
return;
// First, go to the leftmost leaf of the tree
while (node->left != NULL)
node = node->left;
while (node != NULL) {
// Nodes are visited along going upward in the tree
printf("%d\n", node->value);
prev = node;
node = node->right;
if (prev->right_is_child) {
// We're descending into tree
if (node != NULL) {
// Again, go to the leftmost leaf in this subtree
while (node->left != NULL)
node = node->left;
}
}
// else, we're climbing up in the tree
}
}
警告:我没有运行此代码。
答案 1 :(得分:0)
这是用Java编写的代码:
public void inOrder() {
Node<T> curr = root;
boolean visited = false; //I haven't come across the node from which I came
while (curr != null) {
if (!visited && curr.left != null) { //Go to leftmost node
curr = curr.left;
} else {
System.out.println(curr.head + " ");
if (curr.right != null) { //I prioritize having childs than "threaded sons"
curr = curr.right;
visited = false;
} else {
curr = curr.rightThreaded;
visited = true; //Means that I will come back to a node I've already looped, but now i'll print it, except if i'm at the last node
}
}
}
}
Node是ThreadedBinaryTree的内部类:
private static class Node<T> {
private T head;
private Node<T> left;
private Node<T> right;
private Node<T> leftThreaded;
private Node<T> rightThreaded;
public Node(T head, Node<T> leftThreaded, Node<T> rightThreaded) {
this.head = head;
this.leftThreaded = leftThreaded;
this.rightThreaded = rightThreaded;
}
}