作业:二叉树 - 水平顺序横向

时间:2009-12-09 18:49:55

标签: algorithm binary-tree

有没有办法访问从最低级别到较高级别(根)的二叉树?

不是从根级到最低级!!!

(并没有使用水平顺序遍历和堆栈...... !!!)< ---它的对立面......

太难了......谢谢!

5 个答案:

答案 0 :(得分:5)

这里有一些挑战导致不同的解决方案:

  1. 你可以穿越树吗?通常会设置数据结构,因此您只能进行下载。您可以找到所有叶节点,按级别将它们放在优先级队列中,然后遍历。

  2. 您可以存储O(n)个附加数据吗?您可以以正常的广度优先方式遍历它,将指针按级别插入优先级队列,与之前的解决方案一样,但这次在初始遍历期间插入所有节点。这将增加遍历期间使用的辅助数据的最大大小。

  3. 树是否保证平衡和饱满,就像它可能在像树一样的树中?如果是,你可以通过更简单的方式遍历它,只需前往正确的地方。

答案 1 :(得分:0)

如果我理解你的问题是正确的:如果你想遍历首先访问一个叶子而最后一个访问根目录的树,你可以在遍历树的过程中访问返回的节点。

function traverse(node)
    for each child of node
        traverse(child)
    end
    visit(node)
end

如果你想按级别顺序访问节点,你可以做这样的事情(虽然使用堆栈 - 我不确定你是不是想要一个或者某个使用堆栈的特定解决方案):

queue.push(root)
while queue is not empty
    node = queue.pop()
    for each child of node
        queue.push(child)
        stack.push(child)
    end
end
while stack is not empty
    visit(stack.pop())
end

你可以使用一个队列来做,但是时间复杂度更差,如果你这样做:

for i = treedepth down to 0
    queue.push(root)
    while queue is not empty
        node = queue.pop()
        if node has depth i
            visit(node)
        else
            for each child of node
                queue.push(child)
            end
        end
    end
end

如果需要,可以使用初始遍历找到树深度和节点级别。

但是,如果允许进行递归调用,则实际上可以访问堆栈(调用堆栈)。这可以被利用来实现第二个解决方案,但是使堆栈隐含。

function unwind(queue)
    if queue is not empty
        node = queue.pop()
        unwind(queue)
        visit(node)
    end
end

queue.push(root)
while queue is not empty
    node = queue.pop()
    for each child of node
        queue.push(child)
        queue2.push(child)
    end
end

unwind(queue2)

当然,如果您可以访问几乎任何其他数据结构(列表,数组,优先级队列,双端队列等),您可以自己轻松实现堆栈。但是,首先禁止堆栈是没有意义的。

答案 2 :(得分:0)

你可能很容易 IF 你保持了一个指向最大深度节点的指针。如果不这样做,那么在开始遍历之前必须找到该节点。此外,您的节点都必须指向父母。

答案 3 :(得分:0)

我以更好的方式解释。我有一个代数表达式树(所以不平衡)。我必须使用队列(只有队列)来评估它。我问了这个问题,因为我认为唯一的方法是从最低级别开始,直到根...

例如: 树(+(*(2)(2))(3))

我排队并且:

入列(1); 入列(2);

(*)----->出队;出队;结果= 2 * 2;入列(结果); 入队3; (+)----->出队;出队;结果= 4 + 3;给出结果;

所以我需要进行这次遍历:2; 2; *; 3; +

我不知道它是否清楚......

答案 4 :(得分:0)

队列仅用于遍历从树的根到叶的级别顺序。

您可以使用Depth-first Traversal打印特定级别。 像这样:

 void printLevel(BinaryTree *p, int level) {
   if (!p) return;
   if (level == 1) {
     cout << p->data << " ";
   } else {
     printLevel(p->left, level-1);
     printLevel(p->right, level-1);
   }
 }

要从叶子到根打印所有级别,您需要找到树的最大深度。这也可以使用深度优先遍历轻松完成(您可以轻松地谷歌解决方案)。

void printLevelOrder(BinaryTree *root) {
  int height = maxHeight(root);
  for (int level = height; level >= 1; level--) {
    printLevel(root, level);
    cout << endl;
  }
}

运行时复杂度令人惊讶,O(N),其中N是节点的总数。

有关更多信息和运行时复杂性分析,请参阅以下页面:

http://www.ihas1337code.com/2010/09/binary-tree-level-order-traversal-using_17.html