Algorithm 打印二叉树的边界
在一次采访中,我被要求打印二叉树的边界。比如说Algorithm 打印二叉树的边界,algorithm,tree,binary-tree,binary-search-tree,graph-algorithm,Algorithm,Tree,Binary Tree,Binary Search Tree,Graph Algorithm,在一次采访中,我被要求打印二叉树的边界。比如说 1 / \ 2 3 / \ / \ 4 5 6 7 / \ \ 8 9 10 答案是:1,2,4,8,9,10,7,3 我已作出以下答覆 第一种方法: 我使用了Bool变量来解决上述问题 void printLeftEdges(BinaryTree *p, bool print) { if (!p) return; if (print
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10
答案是:1,2,4,8,9,10,7,3
我已作出以下答覆
第一种方法:
我使用了Bool变量来解决上述问题
void printLeftEdges(BinaryTree *p, bool print) {
if (!p) return;
if (print || (!p->left && !p->right))
cout << p->data << " ";
printLeftEdges(p->left, print);
printLeftEdges(p->right, false);
}
void printRightEdges(BinaryTree *p, bool print) {
if (!p) return;
printRightEdges(p->left, false);
printRightEdges(p->right, print);
if (print || (!p->left && !p->right))
cout << p->data << " ";
}
void printOuterEdges(BinaryTree *root) {
if (!root) return;
cout << root->data << " ";
printLeftEdges(root->left, true);
printRightEdges(root->right, true);
}
他的回答是:他对这种方法也不满意。他说你要穿过这棵树三次。这太过分了。如果你有其他解决方案,请给出另一个解决方案
第三种方法:
这一次我选择了级别顺序遍历(BFS)
1:打印各级的起止节点
2:对于每个其他节点,检查其两个子节点是否都为空,然后也打印该节点。
他的回答是:他似乎对这个方法也不满意,因为这个方法需要额外的O(n)阶内存
我的问题是告诉我一个方法,它只遍历一次树,不使用任何Bool变量,也不使用任何额外的内存。有可能吗?我想这应该可以做到:
traverse(BinaryTree *root)
{
if (!root) return;
cout << p->data << " ";
if (root->left ) traverseL(root->left ); //special function for outer left
if (root->right) traverseR(root->right); //special function for outer right
}
traverseL(BinaryTree *p)
{
cout << p->data << " ";
if (root->left ) traverseL(root->left ); //still in outer left
if (root->right) traverseC(root->right);
}
traverseR(BinaryTree *p)
{
if (root->left ) traverseC(root->left );
if (root->right) traverseR(root->right); //still in outer right
cout << p->data << " ";
}
traverseC(BinaryTree *p)
{
if (!root->left && !root->right) //bottom reached
cout << p->data << " ";
else
{
if (root->left ) traverseC(root->left );
if (root->right) traverseC(root->right);
}
}
遍历(二进制树*根)
{
如果(!root)返回;
cout data left)traverseL(根->左);//左外的特殊函数
if(root->right)遍历器(root->right);//外部右的特殊函数
}
traverseL(二进制树*p)
{
cout data left)traverseL(root->left);//仍在左外侧
如果(根->右)遍历(根->右);
}
遍历器(二进制树*p)
{
如果(根->左)遍历(根->左);
if(root->right)遍历器(root->right);//仍在右外侧
cout data left&!root->right)//到达底部
cout data left)遍历(root->left);
如果(根->右)遍历(根->右);
}
}
从遍历
功能开始。
在每个方法的开头去掉了空查询(避免在每一端调用一个函数)。
不需要bool变量,只需使用三种不同的遍历方法:
- 一个用于左边缘,在遍历之前输出节点
- 一个用于右边缘,在遍历后输出节点
- 一个用于所有其他节点,如果没有兄弟节点,则输出该节点
(isLeft,isRight)
,可简化代码并提高O(n)的时间复杂度
方法O(n)没有额外的空间和树的单次遍历。
我将树节点分为四种类型的节点
类型1->形成左边界的节点(如8)
键入0->不构成边界的节点(如12)
类型3->形成右边界的节点(如22)
叶节点(如4,10,14)
在我的方法中,我只是在做树遍历的递归方法(刚刚修改),其中我的函数是这种形式的
void recFunc(btNode *temp,int type)
{
//Leaf Nodes
if((temp->left == NULL)&&(temp->right == NULL))
cout << temp->data << " ";
// type -1 Nodes must be printed before their children
else if(type == 1)cout << temp->data << " ";
else {;}
if(type == 3)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,3);
//type 3 nodes must be printed after their children
cout << temp->data << " ";
}
else if(type == 1)
{
if(temp->left)recFunc(temp->left,1);
if(temp->right)recFunc(temp->right,0);
}
else if(type == 0)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,0);
}
else {;}
}
void recFunc(btNode*temp,int类型)
{
//叶节点
如果((临时->左==NULL)和(&(临时->右==NULL))
无法保留数据,0);
如果(临时->右侧)recFunc(临时->右侧,3);
//类型3节点必须在其子节点之后打印
cout data left)recFunc(临时->左,1);
如果(临时->右侧)recFunc(临时->右侧,0);
}
else if(type==0)
{
如果(临时->左)recFunc(临时->左,0);
如果(临时->右侧)recFunc(临时->右侧,0);
}
else{;}
}
我在哪里改装了汽车
//解决方案的4个不同部分的4个差异列表 1) 左边框2)右边框3)左树中的叶子4)右树中的叶子
public class PRintBinaryTreeBoundary {
ArrayList<TreeNode> leftBorderList=new ArrayList<>();
ArrayList<TreeNode> leftLEafNode=new ArrayList<>();
ArrayList<TreeNode> rightBorderList=new ArrayList<>();
ArrayList<TreeNode> rightLEafNode=new ArrayList<>();
public static void main(String[] args) {
// TODO Auto-generated method stub
/* 1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10*/
TreeNode one=new TreeNode(1);
TreeNode two=new TreeNode(2);
TreeNode three=new TreeNode(3);
TreeNode four=new TreeNode(4);
TreeNode five=new TreeNode(5);
TreeNode six=new TreeNode(6);
TreeNode seven=new TreeNode(7);
TreeNode eight=new TreeNode(8);
TreeNode nine=new TreeNode(9);
TreeNode ten=new TreeNode(10);
one.left=two; one.right=three;
two.left=four;two.right=five;
three.left=six;three.right=seven;
five.left=eight;
six.right=nine;
seven.right=ten;
PRintBinaryTreeBoundary p=new PRintBinaryTreeBoundary();
p.print(one);
}
private void print(TreeNode one) {
System.out.println(one.val);
populateLeftBorderList(one.left);
populateRightBorderList(one.right);
populateLeafOfLeftTree(one.left);
populateLeafOfRightTree(one.right);
System.out.println(this.leftBorderList);
System.out.println(this.leftLEafNode);
System.out.println(this.rightLEafNode);
Collections.reverse(this.rightBorderList);
System.out.println(this.rightBorderList);
}
private void populateLeftBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.leftBorderList.add(n);
n = n.left;
}
}
private void populateRightBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.rightBorderList.add(n);
n = n.right;
}
}
private void populateLeafOfLeftTree(TreeNode leftnode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(leftnode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.leftBorderList.contains(n)) {
leftLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
private void populateLeafOfRightTree(TreeNode rightNode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(rightNode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.rightBorderList.contains(n)) {
rightLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
}
公共类PRintBinaryTreeBoundary{
ArrayList leftBorderList=新建ArrayList();
ArrayList leftLEafNode=新的ArrayList();
ArrayList rightBorderList=新建ArrayList();
ArrayList rightLEafNode=新建ArrayList();
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
/* 1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10*/
TreeNode 1=新的TreeNode(1);
TreeNode 2=新的TreeNode(2);
TreeNode三=新的TreeNode(3);
TreeNode 4=新的TreeNode(4);
TreeNode 5=新的TreeNode(5);
TreeNode 6=新的TreeNode(6);
TreeNode 7=新的TreeNode(7);
TreeNode 8=新的TreeNode(8);
TreeNode九=新的TreeNode(9);
TreeNode十=新的TreeNode(10);
一。左=二;一。右=三;
二。左=四;二。右=五;
三。左=六;三。右=七;
五。左=八;
六.右=九;
七。右=十;
PRintBinaryTreeBoundary p=新的PRintBinaryTreeBoundary();
p、 印刷品(一份);
}
私人作废打印(TreeNode one){
System.out.println(1.val);
公共边界列表(左一);
populateRightBorderList(右一);
一棵树(左一);
一棵恐怖树(右一);
System.out.println(this.leftBorderList);
System.out.println(this.leftLeaf节点);
System.out.println(this.rightleaf节点);
Collections.reverse(此.rightBorderList);
System.out.println(this.rightBorderList);
}
私有void populateLeftBorderList(TreeNode节点){
树节点n=节点;
while(n!=null){
这个.leftBorderList.add(n);
#Print tree boundary nodes
def TreeBoundry(node,isLeft,isRight):
#Left most node and leaf nodes
if(isLeft or isLeaf(node)): print(node.data,end=' ')
#Process next left node
if(node.getLeft() is not None): TreeBoundry(node.getLeft(), True,False)
#Process next right node
if(node.getRight() is not None):TreeBoundry(node.getRight(), False,True)
#Right most node
if(isRight and not isLeft and not isLeaf(node)):print(node.data,end=' ')
#Check is a node is leaf
def isLeaf(node):
if (node.getLeft() is None and node.getRight() is None):
return True
else:
return False
#Get started
#https://github.com/harishvc/challenges/blob/master/binary-tree-edge-nodes.py
TreeBoundry(root,True,True)
void recFunc(btNode *temp,int type)
{
//Leaf Nodes
if((temp->left == NULL)&&(temp->right == NULL))
cout << temp->data << " ";
// type -1 Nodes must be printed before their children
else if(type == 1)cout << temp->data << " ";
else {;}
if(type == 3)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,3);
//type 3 nodes must be printed after their children
cout << temp->data << " ";
}
else if(type == 1)
{
if(temp->left)recFunc(temp->left,1);
if(temp->right)recFunc(temp->right,0);
}
else if(type == 0)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,0);
}
else {;}
}
public class PRintBinaryTreeBoundary {
ArrayList<TreeNode> leftBorderList=new ArrayList<>();
ArrayList<TreeNode> leftLEafNode=new ArrayList<>();
ArrayList<TreeNode> rightBorderList=new ArrayList<>();
ArrayList<TreeNode> rightLEafNode=new ArrayList<>();
public static void main(String[] args) {
// TODO Auto-generated method stub
/* 1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10*/
TreeNode one=new TreeNode(1);
TreeNode two=new TreeNode(2);
TreeNode three=new TreeNode(3);
TreeNode four=new TreeNode(4);
TreeNode five=new TreeNode(5);
TreeNode six=new TreeNode(6);
TreeNode seven=new TreeNode(7);
TreeNode eight=new TreeNode(8);
TreeNode nine=new TreeNode(9);
TreeNode ten=new TreeNode(10);
one.left=two; one.right=three;
two.left=four;two.right=five;
three.left=six;three.right=seven;
five.left=eight;
six.right=nine;
seven.right=ten;
PRintBinaryTreeBoundary p=new PRintBinaryTreeBoundary();
p.print(one);
}
private void print(TreeNode one) {
System.out.println(one.val);
populateLeftBorderList(one.left);
populateRightBorderList(one.right);
populateLeafOfLeftTree(one.left);
populateLeafOfRightTree(one.right);
System.out.println(this.leftBorderList);
System.out.println(this.leftLEafNode);
System.out.println(this.rightLEafNode);
Collections.reverse(this.rightBorderList);
System.out.println(this.rightBorderList);
}
private void populateLeftBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.leftBorderList.add(n);
n = n.left;
}
}
private void populateRightBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.rightBorderList.add(n);
n = n.right;
}
}
private void populateLeafOfLeftTree(TreeNode leftnode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(leftnode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.leftBorderList.contains(n)) {
leftLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
private void populateLeafOfRightTree(TreeNode rightNode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(rightNode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.rightBorderList.contains(n)) {
rightLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
}
// Java program to print boundary traversal of binary tree
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node {
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree {
Node root;
// A simple function to print leaf nodes of a binary tree
void printLeaves(Node node)
{
if (node != null) {
printLeaves(node.left);
// Print it if it is a leaf node
if (node.left == null && node.right == null)
System.out.print(node.data + " ");
printLeaves(node.right);
}
}
// A function to print all left boundary nodes, except a leaf node.
// Print the nodes in TOP DOWN manner
void printBoundaryLeft(Node node)
{
if (node != null) {
if (node.left != null) {
// to ensure top down order, print the node
// before calling itself for left subtree
System.out.print(node.data + " ");
printBoundaryLeft(node.left);
}
else if (node.right != null) {
System.out.print(node.data + " ");
printBoundaryLeft(node.right);
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}
}
// A function to print all right boundary nodes, except a leaf node
// Print the nodes in BOTTOM UP manner
void printBoundaryRight(Node node)
{
if (node != null) {
if (node.right != null) {
// to ensure bottom up order, first call for right
// subtree, then print this node
printBoundaryRight(node.right);
System.out.print(node.data + " ");
}
else if (node.left != null) {
printBoundaryRight(node.left);
System.out.print(node.data + " ");
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}
}
// A function to do boundary traversal of a given binary tree
void printBoundary(Node node)
{
if (node != null) {
System.out.print(node.data + " ");
// Print the left boundary in top-down manner.
printBoundaryLeft(node.left);
// Print all leaf nodes
printLeaves(node.left);
printLeaves(node.right);
// Print the right boundary in bottom-up manner
printBoundaryRight(node.right);
}
}
// Driver program to test above functions
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
tree.root.right = new Node(22);
tree.root.right.right = new Node(25);
tree.printBoundary(tree.root);
}
}
class Node {
Node left;
Node right;
int data;
Node(int d) {
data = d;
left = right = null;
}
}
class BinaryTree {
Node root;
public void getBoundary() {
preorderLeft(root);
inorderLeaves(root);
postorderRight(root);
}
public boolean isLeaf(Node node) {
if (node != null && node.left == null && node.right == null) return true;
return false;
}
public void preorderLeft(Node start) {
if (start != null && isLeaf(start) == false) System.out.print(start.data + " ");
if (start.left != null) preorderLeftSide(start.left);
}
public void inorderLeaves(Node start) {
if(start == null) return;
if(start.left != null) inorderLeaves(start.left);
if(start.left == null && start.right == null) System.out.print(start.data + " ");
if(start.right != null) inorderLeaves(start.right);
}
public void postorderRight(Node start) {
if(start.right != null) postorderRightSide(start.right);
if(start != null && isLeaf(start) == false) System.out.print(start.data + " ");
}
}
map<int,int>tmap; #store the vertical distance and level
list<int>llist; #store the node values
void Buildfunction(root,d, l){
if(root == NULL){
return;
} else if(tmap.count(d) == 0){
tmap[d] = l;
llist.push_back(root->data);
} else if((root->left == NULL && root->right==NULL) || tmap[d] < l){
tmap[d] = l;
llist.push_back(root->data);
}
Buildfunction(root->left,d--,l++);
Buildfunction(root->right,d++,l++);
}
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def printLeaves(root):
if (root):
printLeaves(root.left)
if root.left is None and root.right is None:
print(root.data),
printLeaves(root.right)
def printBoundaryC(node):
if not node.left or not node.right:
print(node.data)
if node.left:
printBoundaryC(node.left)
if node.right:
printBoundaryC(node.right)
def printBoundaryLeft(root):
print(root.data)
if root.left:
printBoundaryLeft(root.left)
if root.right:
printBoundaryC(root.right)
def printBoundaryRight(root):
if root.right:
printBoundaryRight(root.right)
elif root.left:
printBoundaryC(root.left)
print(root.data)
def printBoundary(root):
if (root):
print(root.data)
if root.left:
printBoundaryLeft(root.left)
if root.right:
printBoundaryRight(root.right)
root = Node(20)
root.left = Node(8)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.left.right = Node(5)
root.left.right.right = Node(14)
root.right = Node(22)
root.right.right = Node(25)
printBoundary(root)