2010-09-20 128 views
3

我们给出了一个二叉查找树;我们需要找出它的边界。查找二叉树的边框

因此,如果二进制树

  10 
    /  \ 
    50   150 
    /\  / \ 
    25 75  200 20 
/\   / /\ 
15 35  120 155 250 

应该打印出来50 25 15 35 120 155 250 20 150 10

若二叉树是

   10 
     /  \ 
     50   150 
     /\  / 
     25 75  200 
    /\ /\  
    15 35 65 30 

应该是这样50 25 15 35 65 30 200 150 10

这怎么办?将这个概括为二叉树会使问题变得更困难吗?

任何通过链接的帮助也将不胜感激。

P.S .:请看到模式不是从根开始,而是从左侧开始(在这种情况下)。它也可能从正确的开始,但它总是以根结束。

+0

我也没搞清楚,该算法bit.We需要使用DFS和BFS的组合来得到它... – Flash 2010-09-21 13:34:45

回答

2

你所要求的是修改后的深度优先遍历,其中节点的值只有在1)节点是叶节点或者2)节点沿着树的“外部路径”时才被打印/返回,其中“外部路径”定义为

如果您通过跟踪来自根的所有左侧(或右侧)路径或者节点是否到达节点,节点就是“外部路径”的一部分父亲节点的右边(或左边)孩子本身是“外部路径”的一部分,但没有左(或右)儿童。

如果你知道如何编码DFS,那么这里的修改可以通过在遍历期间检查一些额外的条件来实现。

+0

这是比这更复杂,由于75(叶节点),在不被第一棵树。我认为OP基本上希望节点沿着最左边的分支后面的三角形,然后是最深的层次,然后是最右边的分支。对二叉树来说这不是一个合理的任务。 – 2010-09-20 18:13:18

+0

罢工,我也错了。有什么奇怪的要求。我不认为有两个例子削减它,我们需要规范。 – 2010-09-20 18:18:53

+0

那么我认为你仍然可以遵循相同的基本算法,只需修改条件 - 跟踪树的最大深度,只计算叶节点作为边界的一部分,如果它们的深度==最大深度或节点是左/右子树中最深的节点。使用BFS可能更容易跟踪最大深度。 – 2010-09-21 01:10:29

0

我不确定这个二叉树是否重要。我认为walk算法是一样的。

从左侧子树开始,并执行修改后的宽度第一步,仅当它是左侧兄弟或边缘时才打印节点。这将打印左边的兄弟姐妹,直到它碰到边缘,然后将叶子打印出来。

然后,您首先在右侧树上行走修改后的深度,然后打印右侧兄弟姐妹或树叶。这将打印所有正确的子树叶子,然后打印正确的兄弟姐妹。

+0

同样的解决方案strikedto我也。但是解决方案存在缺陷。当你走左子树时,最后一个元素将是一片叶子。所以当我们打印所有其他叶子时它也会被打印出来。当我们走在右边的子树上时,会发生什么事情。你们如何消除复制两片叶子? – 2011-07-16 17:05:41

0
printBorder(node *n){ 

    printLeft(n); O(log n) 
    printBottom(n); O(n) 
    printRight(n); O(log n) 
} 

printBottom(node *n) 
{ 
    int h = treeHeight(n); 
    printBottomHelper(n, 0); 
} 
printBottomHelper(n, h, max) 
{ 
    if(h == max) { 
    print n->data 
    } 
    printBottomHelper(n->left, h+1, max); 
    printBottomHelper(n->right, h+1, max); 
} 
printLeft(node *n) 
{ 
    while(n!= null){ 
    node *l = n->left; 
    l!= null ? print l->data:1 
    n =l; 
    } 
} 
0

您可以维护两个布尔值来说出要打印的内容。

调用printBorder(root,true,true)开始。编辑:不在最后打印根,但在开始时,应特殊情况下。

function printBorder(
Node node, bool printLeft, bool printRight, int height, const int MAX_HEIGHT) { 
    if (printLeft || printRight || 
    (node.left == null && node.right == null && height == MAX_HEIGHT)) { 
    print node; 
    } 
    if (node.left) printBorder(node.left, printLeft, printRight && node.right==null) 
    if (node.right) printBorder(node.right, printLeft && node.left == null, printRight) 
} 

其中MAX_HEIGHT由maxdepth(root,0);

int maxdepth(Node node, int height) { 
    if (node == null) return height; 
    return max(maxdepth(node.left, height+1), maxdepth(node.right, height+1)) 
} 
+0

现在可以在问题提供的示例树中打印数字75的条件在哪里?对于节点75,node.left为空并且为节点。权利为null。因此,无论printLeft和printRight布尔值是多少,如果你的算法的左右部分为空(但它不一定是一个叶子对吧?),那么你的算法会打印一个节点。 – Barry 2011-12-09 13:36:56

+0

嗯,那就对了。我想,我将不得不首先确定最大深度,然后将其与printBorder一起传递。说实话,现在只有@matt的评论对我有意义。 – gvijay 2011-12-10 02:13:33