打印二叉树的边界

时间:2012-06-28 12:20:30

标签: algorithm binary-tree

如何打印二叉树的外框。

  1. 订单是从上到下,从左到右,然后是从上到下
  2. 打印所有leftest节点和最正常的节点
  3. 打印所有叶节点
  4. 打印所有只有1个叶子的节点

             100
            /   \ 
          50     150
         / \      /
       24   57   130
      /  \    \    \
    12   30    60   132
    
  5. e.g: 输出应该是 100,50,24,12,30,57,60,130,132,150

    如果我们编写三个不同的函数来打印左节点,叶节点和右节点,它可以很容易地解决,但需要O(n + 2logn)时间。

    我也在寻找O(n)方法,但条件是每个节点只应访问一次,不需要额外的O(2logn)部分。

7 个答案:

答案 0 :(得分:3)

这可以在O(n)中完成。也就是说,我们只访问树的每个节点一次。 逻辑如下 保持两个变量并将它们初始化为零。 什么时候有左递增的递归调用1 什么时候有一个递归调用乘坐侧增量 1?

从root开始,进行inorder遍历并检查 right 是否为零,这意味着我们从未对右向进行递归调用。如果是打印节点,这意味着我们正在打印树的所有最左边的节点。如果不为零,则它们不被视为边界,因此查找叶节点并打印它们。

在完成左子树调用之后的Inorder遍历中,您将冒泡到root,然后我们对右子树进行递归调用。现在首先检查叶节点并打印它们,然后检查是否为零,这意味着我们向左进行了递归调用,因此它们不被视为边界。如果为零打印节点,则表示我们正在打印树的所有最右边的节点。

代码段是

void btree::cirn(struct node * root,int left,int right)
{



 if(root == NULL)
    return;
if(root)
{

    if(right==0)
    {

        cout<<root->key_value<<endl;
    }

     cirn(root->left,left+1,right);




if(root->left==NULL && root->right==NULL && right>0)
    {

            cout<<root->key_value<<endl;
    }





  cirn(root->right,left,right+1);
  if(left==0)
   {

       if(right!=0)
      {
            cout<<root->key_value<<endl;
       }


   }




}

}

答案 1 :(得分:1)

<强> ALGO:

  
      
  1. 打印左边界
  2.   
  3. 打印树叶
  4.   
  5. 打印右边界
  6.   

void getBoundaryTraversal(TreeNode t) {
        System.out.println(t.t);
        traverseLeftBoundary(t.left);
        traverseLeafs(t);
        //traverseLeafs(t.right);
        traverseRightBoundary(t.right);
    }
    private void traverseLeafs(TreeNode t) {
        if (t == null) {
            return;
        }
        if (t.left == null && t.right == null) {
            System.out.println(t.t);
            return;
        }
        traverseLeafs(t.left);
        traverseLeafs(t.right);
    }
    private void traverseLeftBoundary(TreeNode t) {
        if (t != null) {
            if (t.left != null) {
                System.out.println(t.t);
                traverseLeftBoundary(t.left);
            } else if (t.right != null) {
                System.out.println(t.t);
                traverseLeftBoundary(t.right);
            }
        }
    }

    private void traverseRightBoundary(TreeNode t) {
        if (t != null) {
            if (t.right != null) {
                traverseRightBoundary(t.right);
                System.out.println(t.t);
            } else if (t.left != null) {
                traverseLeafs(t.left);
                System.out.println(t.t);
            }
        }
    }

TreeNode定义:

class TreeNode<T> {

    private T t;
    private TreeNode<T> left;
    private TreeNode<T> right;

    private TreeNode(T t) {
        this.t = t;
    }
}

答案 2 :(得分:0)

使用应用于树的Euler Tour算法可以实现这一点。见link

或者(如果有权访问)Goodrich等的书。 al(link。here

我希望这会有所帮助

答案 3 :(得分:0)

看起来像家庭工作问题,但我需要练习。十年来我没有做任何关于递归的事情。

void SimpleBST::print_frame()
{
   if (root != NULL)
   {
      cout << root->data;

      print_frame_helper(root->left, true, false);
      print_frame_helper(root->right, false, true);
      cout << endl;
   }
}

void SimpleBST::print_frame_helper(Node * node, bool left_edge, bool right_edge)
{
   if (node != NULL)
   {
      if (left_edge)
         cout << ", " << node->data;

      print_frame_helper(node->left, left_edge && true, false);

      if ((!left_edge) && (!right_edge))
         if ((node->left == NULL) || (node->right == NULL))
            cout << node->data << ", ";

      print_frame_helper(node->right, false, right_edge && true);

      if (right_edge)
         cout << ", " << node->data;
   }
}

答案 4 :(得分:0)

可以通过按预先遍历树来完成解决方案 - O(n) 在下面找到示例代码。 Source and some explanation

Java中的示例代码:

public class Main {
    /**
     * Prints boundary nodes of a binary tree
     * @param root - the root node
     */
    public static void printOutsidesOfBinaryTree(Node root) {

        Stack<Node> rightSide = new Stack<>();
        Stack<Node> stack = new Stack<>();

        boolean printingLeafs = false;
        Node node = root;

        while (node != null) {

            // add all the non-leaf right nodes left
            // to a separate stack
            if (stack.isEmpty() && printingLeafs && 
                    (node.left != null || node.right != null)) {
                rightSide.push(node);
            }

            if (node.left == null && node.right == null) {
                // leaf node, print it out
                printingLeafs = true;
                IO.write(node.data);
                node = stack.isEmpty() ? null : stack.pop();
            } else {
                if (!printingLeafs) {
                    IO.write(node.data);
                }

                if (node.left != null && node.right != null) {
                    stack.push(node.right);
                }
                node = node.left != null ? node.left : node.right;
            }
        }

        // print out any non-leaf right nodes (if any left)
        while (!rightSide.isEmpty()) {
            IO.write(rightSide.pop().data);
        }
    }
}

答案 5 :(得分:0)

这是一个简单的解决方案:

def printEdgeNodes(root, pType, cType):
   if root is None:
       return
   if pType == "root" or (pType == "left" and cType == "left") or (pType == "right" and cType == "right"):
        print root.val
   if root.left is None and root.right is None:
       print root.val
   if pType != cType and pType != "root":
       cType = "invalid"
   printEdgeNodes(root.left, cType, "left")

def printEdgeNodes(root):
    return printEdgeNodes(root, "root", "root")

答案 6 :(得分:0)

您可以递归遍历每个节点并控制何时打印,这是javascript代码段。

function findBtreeBoundaries(arr, n, leftCount, rightCount) {
  n = n || 0;
  leftCount = leftCount || 0;
  rightCount = rightCount || 0;

  var length = arr.length;
  var leftChildN = 2*n + 1, rightChildN = 2*n + 2;

  if (!arr[n]) {
    return;
  }

  // this is the left side of the tree
  if (rightCount === 0) {
    console.log(arr[n]);
  }

  // select left child node
  findBtreeBoundaries(arr, leftChildN, leftCount + 1, rightCount);

  // this is the bottom side of the tree
  if (leftCount !== 0 && rightCount !== 0) {
    console.log(arr[n]);
  }

  // select right child node
  findBtreeBoundaries(arr, rightChildN, leftCount, rightCount + 1);

  // this is the right side of the tree
  if (leftCount === 0 && rightCount !== 0) {
    console.log(arr[n]);
  }

}

findBtreeBoundaries([100, 50, 150, 24, 57, 130, null, 12, 30, null, 60, null, 132]);