我们获得了一个二叉搜索树;我们需要找出它的边界。
所以,如果二叉树是
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 :(得分:2)
您要求的是修改后的深度优先遍历,其中只有1)节点是叶节点或2)节点沿树的“外部路径”,才打印/返回节点的值,其中“外部路径”定义为
如果您通过跟踪根目录中的所有左(或右)路径到达节点,或者节点是父节点的右(或左)子节点,则节点是“外部路径”的一部分节点本身是“外部路径”的一部分,但没有左(或右)子节点。
如果您知道如何编写DFS代码,那么可以通过在遍历期间检查一些额外条件来实现此处的修改。
答案 1 :(得分:0)
我不确定这是否是二元树是否重要。我认为walk算法在任何一种方式都是一样的。
从左子树开始,并进行修改后的广度优先行走,只有当它是左兄弟或边缘时才打印节点。这将打印左兄弟姐妹,直到它碰到边缘,然后打印出来。
然后在右侧树上进行修改后的深度优先行走,打印出正确的兄弟或叶子。这将打印所有正确的子树叶,然后是正确的兄弟树。
答案 2 :(得分: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;
}
}
答案 3 :(得分:0)
你可以保留两个布尔值来说明要打印的内容。
调用printBorder(root,true,true)开始。编辑:最后不打印root,但在开始时,应该是特殊情况。
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(root,0)找到MAX_HEIGHT的地方;
int maxdepth(Node node, int height) {
if (node == null) return height;
return max(maxdepth(node.left, height+1), maxdepth(node.right, height+1))
}