![](/img/trans.png)
[英]How to print a tree on levels, given a struct that holds the value of the node and the value of it's parent, for each node in the tree
[英]Binary tree where value of each node holds the sum of child nodes
在接受采訪時我問過這個問題。 我們如何轉換BT以使其中的每個節點都具有一個值,該值是其子節點的總和?
為每個節點提供附加值。 構造樹時,設置葉子的值; 構造內部節點的值為leaf1.value + leaf2.value
。
如果您可以更改葉節點的值,則操作必須“備份”更新總和值的樹。
如果要么在節點中包含反向鏈接,要么將樹實現為“ 線程樹 ”,這將更容易。
這是一個可以幫助您的解決方案:(鏈接用樹形圖解釋)
/* 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);
}
}
請參閱鏈接以查看完整的解決方案和說明!
正如Charlie指出的那樣,你可以簡單地在每個內部節點中存儲各個子樹大小的總和,並在構造時提供常量值(或者如果你只對樹中的葉子數感興趣,則總是隱式使用1) )。
這通常稱為增強搜索樹。
有趣的是,通過這種擴充,即存儲額外的每節點數據,您還可以為樹中的項目導出其他類型的聚合信息。 您可以表示為可以存儲在增強樹中的monoid的任何信息,為此,您需要指定:
所以除了子樹大小,你還可以表達如下內容:
(這個概念讓人聯想到堆,或更明確的treaps,它存儲隨機優先級與內部節點進行概率平衡。它也常見於Finger Trees的上下文中,盡管這些並不相同。)
如果你還為你的幺半群提供一個中性元素,那么你可以走下這樣一個幺半群增強的搜索樹來檢索特定的元素(例如,“找到我的第五片葉子”為你的大小例子;“給我最高的葉子優先”)。
嗯,反正。 可能會在那里被帶走......我碰巧發現這個話題非常有趣。 :)
這是總和問題的代碼。 它的工作原理我測試過它。
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.