如何打印二叉树的外框。
打印所有只有1个叶子的节点
100
/ \
50 150
/ \ /
24 57 130
/ \ \ \
12 30 60 132
e.g: 输出应该是 100,50,24,12,30,57,60,130,132,150
如果我们编写三个不同的函数来打印左节点,叶节点和右节点,它可以很容易地解决,但需要O(n + 2logn)时间。
我也在寻找O(n)方法,但条件是每个节点只应访问一次,不需要额外的O(2logn)部分。
答案 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:强>
- 打印左边界
- 打印树叶
- 打印右边界
醇>
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)
答案 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]);