问题陈述
您将获得指向二叉树根的指针。打印二叉树的顶视图。 您只需要完成该功能。
我的代码:
void top_view(Node root)
{
Node r = root;
if(r.left!=null){
top_view(r.left);
System.out.print(r.data + " ");
}
if(r.right!=null){
System.out.print(r.data + " ");
top_view(r.right);
}
}
每次调用函数时都会执行两个if语句,但我只需要执行其中一个。我尝试过切换但是它给出了常量表达式错误。我已经为这个问题找到了不同的解决方案。
所以我只想知道,如果一次执行,我们是否只能制作一个,即有没有办法修改我的代码而不改变方法?
答案 0 :(得分:7)
您的方法不会有效,因为当您致电left
或right
子树时,您只会坚持下去。这种方法的问题在于你只是首先调用树的哪一侧。
可能你可以通过使用堆栈和队列来解决它,就像其他人说的那样但我觉得以下是一种更简单,更直观的方法:
(最后看到代码,非常简单)
解决此问题的方法是从root用户维护horizontal distance
,然后为每个不同的horizontal distance
打印第一个节点。
什么是水平距离?
我只是拍摄你添加的图像。
特定
Horizontal distance
的 node
定义为从根水平的数量。如果你看到没有边缘会变成垂直距离。
为了让根目录左侧的所有节点更容易,以-ve水平距离和右侧正距离开始。
如何计算水平距离?
如果你向右走add 1
,如果你要离开,请添加-1
。
所以
horizontal distance of 3 = 0
horizontal distance of 5 = -1
horizontal distance of 1 = -2
horizontal distance of 9 = -1
horizontal distance of 4 = 0
horizontal distance of 2 = 1
horizontal distance of 6 = 0
horizontal distance of 7 = 2
horizontal distance of 8 = 0
节点3,4,6,8
的水平距离相同0
是什么意思?
这意味着当你从顶部看到所有这些节点在它上面的垂直线上时。
如果它们垂直排成一行你看到了什么?
可以从root首先到达。
您如何找到可以首先到达哪一个?
像往常一样 BFS如何为您的示例打印解决方案?
有五种不同的水平距离值{-1,-2,0,1,2}
hor dist Nodes
0 - {3,6,8} // 3 comes first in BFS so print 3
-1 - {5,9} // 5 comes first in BFS so print 5
-2 - {1} // just print 1
1 - {2} // just print 2
2 - {7} // just print 7
所以它会打印{3,5,1,2,7}
HashSet<Integer> set = new HashSet<>();
Queue<QueueItem> queue = new LinkedList<>();
queue.add(new QueueItem(root, 0)); // Horizontal distance of root is 0
while (!queue.isEmpty())
{
QueueItem temp = queue.poll();
int hd = temp.hd;
TreeNode n = temp.node;
// If this is the first node at its horizontal distance,
// then this node is in top view
if (!set.contains(hd))
{
set.add(hd);
System.out.print(n.key + " ");
}
if (n.left != null)
queue.add(new QueueItem(n.left, hd-1));
if (n.right != null)
queue.add(new QueueItem(n.right, hd+1));
}
答案 1 :(得分:2)
使用以下方法可以很容易地解决这个问题:
堆栈:打印根和左子树。
队列:打印正确的子树。
你的功能应该是这样的:
void topview(Node root)
{
if(root==null)
return;
Stack<Integer> s=new Stack<Integer>();
s.push(root.data);
Node root2=root;
while(root.left!=null)
{
s.push(root.left.data);
root=root.left;
}
while(s.size()!=0)
System.out.print(s.pop()+" ");
Queue<Integer> q=new LinkedList<Integer>();
q.add(root2.right.data);
root2=root2.right;
while(root2.right!=null)
{
q.add(root2.right.data);
root2=root2.right;
}
while(q.size()!=0)
System.out.print(q.poll()+" ");
}
答案 2 :(得分:1)
这个实际上有效。不需要队列,但是使用堆栈从左侧回溯,因为我们没有引用父级。
void top_view(Node root)
{
Stack<Node> p = new Stack<Node>();
Node current = root;
while (current != null)
{
p.push(current);
current = current.left;
}
while (p.peek() != root)
{
System.out.print(p.pop().data + " ");
}
current = root;
while (current != null)
{
System.out.print(current.data + " ");
current = current.right;
}
}
答案 3 :(得分:0)
以上某些答案无效。我曾尝试对它们发表评论,但是很显然,我的评分不正确,因为我之前从未尝试在此处发表评论。
问题是您需要对树进行广度优先搜索,以确保节点的正确顺序。为了排除“模糊”节点,另一个网站建议对每个节点进行排名。根为0。节点左侧的所有分支的父级为-1。右边的所有分支的父级为+1。祖先等级重复的所有节点都将被排除。
然后按等级顺序打印出选定的节点。在所有情况下都可以使用。
答案 4 :(得分:0)
def printTopView(root):
lst=[]
current1=root.left
while current1!=None:
lst.append(current1.key)
current1=current1.left
lst.reverse()
current2=root
while current2!=None:
lst.append(current2.key)
current2=current2.right
print(*lst)
答案 5 :(得分:0)
Python解决方案
def topView(root):
q = deque()
#Adding root node to the deque along with its Horizontal Distance from root.
q.append([root,0])
#Dictionary to store the {Horizontal Distance: First Node that has this distance}
s = {}
#Breadth First Traversal - [To keep track of the first Node that is visited.]
while q:
temp = q.popleft()
#Horizontal Distance from Root
d = temp[1]
#Adding the Left Child to the Queue (if Exists)
if temp[0].left is not None:
q.append([temp[0].left, d-1])
#Adding the Right Child to the Queue (if Exists)
if temp[0].right is not None:
q.append([temp[0].right, d+1])
#Adding the Horizontal Distance and the First Node that has this distance to Dictionary.
if d not in s:
s[d] = temp[0].info
#Printing out the Top View of Tree based on the values in the Dictionary - From least to Highest Horizontal Distance from Root Node.
for i in sorted(s):
print(s[i], end=" ")
答案 6 :(得分:0)
此:
for loops
一直是适用于Python的解决方案,但由于某些原因,它在hackerrank.com上的7个测试案例中有6个失败。有人可以解释一下为什么会这样吗?
那些只运行“向左”和“向右”功能的人不了解任务。
答案 7 :(得分:0)
可以在此处找到解决方案 - Git hub URL
请注意,无论hackerrank问题是关于平衡树,如果树处于不平衡状态,如下所示
"Sending email to the following rbrown at email address $rbrownEmail
对于这些类型的树,需要一些复杂的逻辑,这在geeksforgeeks中定义 - GeeksforGeeks
答案 8 :(得分:0)
最简单的递归解决方案
void top_view(Node root)
{
// For left side of the tree
top_view_left(root);
// For Right side of the tree
top_view_right(root.right);
}
void top_view_left(Node root){
if(root != null)
{
// Postorder
top_view_left(root.left);
System.out.print(root.data + " ");
}
}
void top_view_right(Node root){
if(root != null)
{
// Preorder
System.out.print(root.data + " ");
top_view_right(root.right);
}
}
答案 9 :(得分:0)
这是c ++中二叉树顶视图的代码..
void topview(node * root,queue&amp; Q)
{
if(!root)
return;
map<int,int> TV;
Q.push(root);
TV[root->data]=0;
map<int,int>:: iterator it;
int min=INT_MAX,max=INT_MIN;
while(!Q.empty())
{
node* temp =Q.front();
Q.pop();
int l=0;
for(it=TV.begin();it!=TV.end();it++)
{
if(it->first==temp->data)
{
l=it->second;
break;
}
}
if(l<min)
{min=l;}
if(l>max)
max=l;
if(temp->left)
{
Q.push(temp->left);
TV[temp->left->data] = l-1;
}
if(temp->right)
{
Q.push(temp->right);
TV[temp->right->data] = l+1;
}
}
cout<<max<<min<<endl;
for(int i =min;i<=max;i++)
{
for(it=TV.begin();it!=TV.end();it++)
{
if(it->second==i)
{
cout<<it->first;
break;
}
}
}
}
void topview_aux(node * root)
{
queue<node*> Q;
topview(root,Q);
}
答案 10 :(得分:0)
ng-change
答案 11 :(得分:0)
一种简单的递归方式:
void top_view(Node root)
{
print_top_view(root.left, "left");
System.out.print(root.data + " ");
print_top_view(root.right, "right");
}
void print_top_view(Node root, String side) {
if(side.equals("left")) {
if(root.left != null) {
print_top_view(root.left, "left");
}
System.out.print(root.data + " ");
} else if(side.equals("right")) {
System.out.print(root.data + " ");
if(root.right != null) {
print_top_view(root.right, "right");
}
}
}
答案 12 :(得分:0)
void top_view(Node root)
{
Node left = root;
Node right = root;
print_left(root.left);
System.out.print(root.data + " ");
print_right(root.right) ;
}
void print_left(Node start)
{
if(start != null)
{
print_left(start.left);
System.out.print(start.data + " ");
}
}
void print_right(Node start)
{
if(start != null)
{
System.out.print(start.data + " ");
print_right(start.right);
}
}
答案 13 :(得分:0)
在java recursivish解决方案中。从c ++代码转换而来
void top_view(Node root)
{
left_array(root);
right_array(root.right);
}
void left_array(Node p)
{
if(p==null)
return;
else
{
left_array(p.left);
System.out.printf("%d ",p.data);
}
}
void right_array(Node p)
{
if(p==null)
return;
else
{
System.out.printf("%d ",p.data);
right_array(p.right);
}
}
答案 14 :(得分:0)
一个非常简单的递归解决方案,负责处理子节点的长分支。这是使用水平距离概念解决的。
public void printTopView(BNode root) {
Map<Integer, Integer> data = new TreeMap<Integer, Integer>();
printTopViewRecursive(data, root, 0);
for(int key : data.keySet()) {
System.out.print(data.get(key) +" ");
}
}
private void printTopViewRecursive(Map<Integer, Integer> hDMap, BNode root, int hD) {
if(root == null)
return;
if(!hDMap.containsKey(hD)) {
hDMap.put(hD, root.data);
}
printTopViewRecursive(hDMap, root.left,hD - 1);
printTopViewRecursive(hDMap, root.right, hD + 1);
}
答案 15 :(得分:0)
C ++中更简单的方法
`// printing top view of the tree
void left_array(node *p)
{
if(p==NULL)
return;
else
{
left_array(p->left);
cout<<p->data<<" ";
}
}
void right_array(node *p)
{
if(p==NULL)
return;
else
{
cout<<p->data<<" ";
right_array(p->right);
}
}
void top_view(node * root)
{ int i=0;
node *t1=root;
node *t2=root;
left_array(t2);
right_array(t1->right);
}`
答案 16 :(得分:0)
void top_view(Node root)
{
if(root.left!=null) top_view(root.left);
if(root.left!=null || root.right!=null)
System.out.print(root.data + " ");
if(root.right!=null) top_view(root.right);
}