我们可以在不使用O(n)中的队列的情况下对订单打印二进制搜索树吗?

时间:2015-04-10 19:25:19

标签: algorithm language-agnostic

我们是否可以在不使用具有O(n)时间复杂度的队列的情况下按级别顺序打印BST?下面是一个c ++代码,在没有队列的最坏情况下在O(n ^ 2)中执行。我想知道我们是否可以在O(n)中获得相同的结果。如果没有,我们至少可以改进这个算法吗?

int height(Node* root) {
    if (root==NULL) return -1;
    int h1 = height(root->left);
    int h2 = height(root->right);
    return max(h1, h2) + 1;
}

void printLevel(Node* root, int level) {
    if (!root) return;
    if (level==0) {
        cout << root->data << " ";
        return;
    }
    printLevel(root->left, level - 1);
    printLevel(root->right, level - 1);
}
void print(Node* root) {
    int h=height(root);
    for (int i = 0; i <= h ; i++) {
        printLevel(root, i);
    }
    cout << endl;
}

1 个答案:

答案 0 :(得分:0)

当然可以。您可以在每个节点中维护额外信息,这些信息指向:

  • 此级别的下一个项目(如果有);或
  • 另一个级别的第一个项目。

这是在搜索树上叠加一个队列,它看起来像:

      A        > (B)
    _/ \_
   /     \
  B   >   C    > (D)
 / \     / \
D > E > F > G  > (null)

然后,只需遵循不同的指针链即可获得广度优先搜索(BFS)顺序。

但是,这可能会使更新变得非常复杂,并且每个节点将需要更多存储空间。

实际上更多有效(空间)使用队列方法,因为您的队列与树中的额外指针不同,往往不会在其中包含所有条目一旦。实际上,它不会从不直接相邻的级别中包含元素。

举例来说,检查BFS的经典代码:

add root to queue
while queue is not empty:
    get node from queue
    do something with node

    if node.left exists:
        add it to queue
    if node.right exists:
        add it to queue

那就是它,它真的没有比那更简单。而且,在添加子节点之前,您正在从队列中读取条目这一事实意味着存储要求 less 是前面提到的叠加队列解决方案。

最重要的是,当您发现像基于队列的BFS算法一样优雅和简单的东西时,您希望在决定尝试不同的方法之前认真思考非常