这是我遇到的代码,它计算二叉树中的垂直和。由于代码根本没有任何文档,我无法理解它是如何工作的以及if(base == hd)的条件究竟是什么? 需要帮助:)
void vertical_line(int base,int hd,struct node * node)
{
if(!node) return;
vertical_line(base-1,hd,node->left);
if(base==hd) cout<<node->data<<" ";
vertical_line(base+1,hd,node->right);
}
void vertical_sum(struct node * node)
{
int l=0,r=0;
struct node * temp=node;
while(temp->left){
--l;temp=temp->left;
}
temp=node;
while(temp->right){
++r;temp=temp->right;
}
for(int i=l;i<=r;i++)
{
cout<<endl<<"VERTICAL LINE "<<i-l+1<<" : ";
vertical_line(0,i,node);
}
}
答案 0 :(得分:1)
它试图以垂直顺序显示树 - 让我们试着了解什么是垂直顺序
以下面的树为例
4
2 6
1 3 5 7
以下是跨垂直线的节点分布
垂直线1 - 1
垂直线2 - 2
垂直线3 - 3,4,5
垂直线4 - 6
垂直线5 - 7
我们如何确定3,4,5是垂直线3的一部分。我们需要从根找到节点的水平距离,以确定它们是否属于同一条线。我们从水平距离为零的根开始。如果我们向左移动那么我们需要将父级的距离递减1,如果我们向右移动,我们需要将父级的距离递增1.同样适用于树中的每个节点,即如果父级具有水平距离d,则它离开孩子的距离是d-1而右孩子的距离是d + 1
在这种情况下,节点4的距离为0.节点2的子节点为4,因此它的距离为-1(减1)。节点6是4的右子,所以它的距离是1(递增1)。
节点2的距离为-1。节点3是2的右子节点,因此距离为0(增量为1) 类似地,对于节点5.节点3,4,5的水平距离为零,因此它们落在相同的垂直线上
现在来看你的代码
while(temp->left){
--l;temp=temp->left;
}
在这个循环中,你计算最左边节点与左手边的距离(这不会一直有效,我们稍后会讨论)。每次向左移动,你都会将l的值减1。
while(temp->right){
++r;temp=temp->right;
}
使用类似于上面的逻辑,你是计算最远节点与右手边根的距离
现在您知道左侧和右侧的最远距离,您正在垂直显示节点
for(int i=l;i<=r;i++)
{
cout<<endl<<"VERTICAL LINE "<<i-l+1<<" : ";
vertical_line(0,i,node);
}
上面循环中的每次迭代都会在垂直线上显示节点。 (这不高效)。您为每一行调用vertical_line方法
void vertical_line(int base,int hd,struct node * node)
{
if(!node) return;
vertical_line(base-1,hd,node->left);
if(base==hd) cout<<node->data<<" ";
vertical_line(base+1,hd,node->right);
}
上面的方法将打印落在线路hd上的节点。该方法迭代整个树,计算每个节点的距离,即base包含节点的水平距离值。如果一个节点是垂直线hd的一部分,那么base变为等于hd,即base = hd,这是你的代码打印节点的值时