[英]Binary tree where value of each node holds the sum of child nodes
This question was asked of me in an interview. 在接受采访时我问过这个问题。 How can we convert a BT such that every node in it has a value which is the sum of its child nodes?
我们如何转换BT以使其中的每个节点都具有一个值,该值是其子节点的总和?
Give each node an attached value. 为每个节点提供附加值。 When you construct the tree, the value of a leaf is set;
构造树时,设置叶子的值; construct interior nodes to have the value
leaf1.value + leaf2.value
. 构造内部节点的值为
leaf1.value + leaf2.value
。
If you can change the values of the leaf nodes, then the operation has to go "back up" the tree updating the sum values. 如果您可以更改叶节点的值,则操作必须“备份”更新总和值的树。
This will be a lot easier if you either include back links in the nodes, or implement the tree as a " threaded tree ". 如果要么在节点中包含反向链接,要么将树实现为“ 线程树 ”,这将更容易。
Here is a solution that can help you: (the link explains it with tree-diagrams) 这是一个可以帮助您的解决方案:(链接用树形图解释)
Convert an arbitrary Binary Tree to a tree that holds Children Sum Property 将任意二进制树转换为包含Children Sum属性的树
/* This function changes a tree to to hold children sum
property */
void convertTree(struct node* node)
{
int left_data = 0, right_data = 0, diff;
/* If tree is empty or it's a leaf node then
return true */
if(node == NULL ||
(node->left == NULL && node->right == NULL))
return;
else
{
/* convert left and right subtrees */
convertTree(node->left);
convertTree(node->right);
/* If left child is not present ten 0 is used
as data of left child */
if(node->left != NULL)
left_data = node->left->data;
/* If right child is not present ten 0 is used
as data of right child */
if(node->right != NULL)
right_data = node->right->data;
/* get the diff of node's data and children sum */
diff = left_data + right_data - node->data;
/* If node's data is smaller then increment node's data
by diff */
if(diff > 0)
node->data = node->data + diff;
/* THIS IS TRICKY --> If node's data is greater then increment left
subtree by diff */
if(diff < 0)
increment(node->left, -diff);
}
}
See the link to see the complete solution and explanation! 请参阅链接以查看完整的解决方案和说明!
Well as Charlie pointed out, you can simply store the sum of respective subtree sizes in each inner node, and have leaves supply constant values at construction (or always implicitly use 1, if you're only interested in the number of leaves in a tree). 正如Charlie指出的那样,你可以简单地在每个内部节点中存储各个子树大小的总和,并在构造时提供常量值(或者如果你只对树中的叶子数感兴趣,则总是隐式使用1) )。
This is commonly known as an Augmented Search Tree. 这通常称为增强搜索树。
What's interesting is that through this kind of augmentation, ie, storing additional per-node data, you can derive other kinds of aggregate information for items in the tree as well. 有趣的是,通过这种扩充,即存储额外的每节点数据,您还可以为树中的项目导出其他类型的聚合信息。 Any information you can express as a monoid you can store in an augmented tree, and for this, you'll need to specify:
您可以表示为可以存储在增强树中的monoid的任何信息,为此,您需要指定:
So besides subtree sizes, you can also express stuff like: 所以除了子树大小,你还可以表达如下内容:
(This concept is rather reminiscent of heaps, or more explicitly treaps, which store random priorities with inner nodes for probabilistic balancing. It's also quite commonly described in the context of Finger Trees, although these are not the same thing.) (这个概念让人联想到堆,或更明确的treaps,它存储随机优先级与内部节点进行概率平衡。它也常见于Finger Trees的上下文中,尽管这些并不相同。)
If you also provide a neutral element for your monoid, you can then walk down such a monoid-augmented search tree to retrieve specific elements (eg, "find me the 5th leaf" for your size example; "give me the leaf with the highest priority"). 如果你还为你的幺半群提供一个中性元素,那么你可以走下这样一个幺半群增强的搜索树来检索特定的元素(例如,“找到我的第五片叶子”为你的大小例子;“给我最高的叶子优先”)。
Uhm, anyways. 嗯,反正。 Might have gotten carried away a bit there.. I just happen to find that topic quite interesting.
可能会在那里被带走......我碰巧发现这个话题非常有趣。 :)
:)
Here is the code for the sum problem. 这是总和问题的代码。 It works i have tested it.
它的工作原理我测试过它。
int sum_of_left_n_right_nodes_4m_root(tree* local_tree){
int left_sum = 0;
int right_sum = 0;
if(NULL ==local_tree){
return 0;
}
if((NULL == local_tree->left)&&(NULL == local_tree->right)){
return 0;
}
sum_of_left_n_right_nodes(local_tree->left);
sum_of_left_n_right_nodes(local_tree->right);
if(NULL != local_tree->left)
left_sum = local_tree->left->data +
local_tree->left->sum;
if(NULL != local_tree->right)
right_sum = local_tree->right->data + \
local_tree->right->sum;
local_tree->sum= right_sum + left_sum;
}
使用递归函数,您可以通过使每个节点的值等于它的子节点的值的总和,条件是它有两个子节点,或者它的单个子节点的值(如果它有一个子节点),如果它有没有孩子(叶子),那么这是破坏条件,价值永远不会改变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.