Algorithm 寻找二叉树的边界

Algorithm 寻找二叉树的边界,algorithm,binary-tree,tree-traversal,Algorithm,Binary Tree,Tree Traversal,我们得到一个二叉搜索树;我们需要找出它的边界 所以,如果二叉树是 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    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  
它应该像
50251535630200150 10

如何做到这一点?将其推广到二叉树会使问题变得更难吗

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


注意:请注意图案不是从根开始,而是从左边开始(在本例中)。它也可以以right开头,但始终以root结尾。

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

如果通过从根节点跟随所有左(或右)路径到达节点,或者如果节点是父节点的右(或左)子节点,而父节点本身是“外部路径”的一部分,但没有左(或右)子节点,则节点是“外部路径”的一部分


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

我不确定这是否是二叉树。我认为步行算法在任何一种情况下都是一样的

从左子树开始,执行修改后的宽度优先遍历,仅当节点是左同级节点或边时才打印节点。这将打印左侧同级,直到它碰到边缘,然后打印出叶子


然后在右边的树上执行修改后的深度优先行走,该树打印右边的兄弟树或叶子。这将打印所有正确的子树叶子,然后打印正确的同级树。

您可以保留两个布尔值来指定要打印的内容

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;
  }
}
调用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)
}
其中,由maxdepth(根,0)找到的最大高度


因为75(叶节点)不在第一棵树中,所以它比这更复杂。我认为OP基本上想要的是沿着三角形的节点,沿着最左边的分支,然后是最深的层次,然后是最右边的分支。对于二叉树来说,这不是一个合理的任务。算了,我也错了。多么奇怪的要求。我不认为有两个例子可以解决这个问题,我们需要规范。那么我认为你仍然可以遵循相同的基本算法,只需修改条件-跟踪树的最大深度,如果叶节点的深度=最大深度,或者该节点是左/右子树中最深的节点,则只将叶节点作为边界的一部分计算。使用BFS跟踪最大深度可能更容易。我确实找到了一点算法。我们需要使用DFS和BFS的组合来获得它…我也遇到了相同的解决方案。但解决方案中存在一个缺陷。走左边的子树时,最后一个元素将是一片叶子。所以当我们打印所有其他叶子时,它也会被打印出来。当我们在右边的子树上行走时,同样的情况也会发生。如何消除两片叶子的重复?现在允许打印问题提供的示例树中的75号的条件在哪里?对于节点75,node.left为空,node为空。右边是空的。因此,不管printLeft和printRight布尔值是多少,如果节点的左侧和右侧为空(但它不一定是叶右侧?),那么算法都会打印节点。嗯,没错。我想,我必须先通过确定最大深度,然后通过printBorder。老实说,直到现在@matt的评论才对我有意义。
int maxdepth(Node node, int height) {
  if (node == null) return height;
  return max(maxdepth(node.left, height+1), maxdepth(node.right, height+1))
}