【问题标题】:Iterative Threaded Binary Tree Traversing with only constant extra space仅具有恒定额外空间的迭代线程二叉树遍历
【发布时间】:2012-05-06 18:59:07
【问题描述】:

如何在O(n)中非递归地遍历线程二叉树而不使用堆栈(只允许为临时变量使用恒定的额外空间,所以我们可以'不要将访问标志添加到树中的每个节点)。我花了很长时间思考这个问题,但在我看来这并不可行除非我们要遍历具有树数据的内存位置。假设我们使用多个数组表示来实现指针,那么我们可以在 O(n) 中遍历树,有没有其他想法?

注意不是作业,只是为了节省一些键盘敲击的能量来写关于作业的cmets!

【问题讨论】:

  • 你看过Wikipedia吗?
  • @svick 算法的第二步是 Step-2:将左子节点放入已访问节点列表中,并将其设为当前节点。转到步骤 6。 我在问题中提到我需要使用 constant extra space
  • 我的回答与您的问题相关吗?如果有,请将其标记为一个。如果不是,请说明原因,我会尽力完善它。

标签: data-structures binary-tree tree-traversal non-recursive


【解决方案1】:

假设我们在 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
    }
}

警告:我还没有运行此代码。

【讨论】:

    【解决方案2】:

    这是用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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 2012-01-01
      相关资源
      最近更新 更多