📌  相关文章
📜  根据子树权重的差异,打印完整二叉树的每个节点的更新级别

📅  最后修改于: 2021-05-04 08:46:52             🧑  作者: Mango

给定一个完整的二叉树从根到最低层的N个级别从低到高依次为[0,(N – 1)]权重从根到最后一个叶节点之间的重在[1,2 N – 1]之间。按照递增顺序,每个节点的任务是根据以下条件调整其左右子树中存在的所有节点的级别值:

  • 通过权重的差异增加较轻子树的所有节点的级别。
  • 通过权重的差异降低较重子树的所有节点的级别。

例子:

方法:为了解决此问题,我们为每个节点计算左(w_left)和右(w_right)子树的权重,并存储它们的差K。一旦计算,我们从其各自的当前值递归地将其较轻的子树的所有节点的水平值增加K,并将其较重的子树的所有节点的水平值降低K。计算完所有节点后,我们将显示每个节点级别的最终值。
下面的代码是上述方法的实现:

C++
1
        /   \
       2     3


Java
1
           /   \
          2     3
         / \   / \
        4   5 6   7


Python3
// C++ Program to print updated levels
// of each node of a Complete Binary Tree
// based on difference in weights of subtrees
 
#include 
using namespace std;
 
// Node for the given binary tree
struct node {
 
    int weight;
 
    // stores the weight of node
    int level;
 
    // stores the level of node
    struct node* left;
    struct node* right;
 
    node(int w, int l)
    {
        this->weight = w;
        this->level = l;
        left = right = NULL;
    }
};
 
// Utility function to insert a node
// in a tree rooted at root
struct node* insert(struct node* root,
 int n_weight,
int n_level, queue& q)
{
 
    struct node* n
= new node(n_weight, n_level);
 
    // if the tree is empty till now
    // make node n the root
    if (root == NULL)
        root = n;
 
    // If the frontmost node of
    // queue has no left child
    // make node n its left child
    // the frontmost node still
    // remains in the queue because
    // its right child is null yet
    else if (q.front()->left == NULL) {
        q.front()->left = n;
    }
 
    // Make node n the right child of
    // the frontmost node and remove
    // the front node from queue
    else {
        q.front()->right = n;
        q.pop();
    }
    // push the node n into queue
    q.push(n);
 
    return root;
}
 
// Function to create a complete binary tree
struct node* createTree(vector weights,
vector levels)
{
 
    // initialise the root node of tree
    struct node* root = NULL;
 
    // initialise a queue of nodes
    queue q;
 
    int n = weights.size();
    for (int i = 0; i < n; i++) {
 
        /*
        keep inserting nodes with weight values
        from the weights vector and level values
        from the levels vector
        */
        root = insert(root, weights[i],
        levels[i], q);
    }
    return root;
}
 
// Function to print final levels of nodes
void printNodeLevels(struct node* root)
{
 
    if (root == NULL)
        return;
 
    queue q;
    q.push(root);
 
    while (!q.empty()) {
 
        cout << q.front()->level << " ";
 
        if (q.front()->left != NULL)
            q.push(q.front()->left);
        if (q.front()->right != NULL)
            q.push(q.front()->right);
        q.pop();
    }
    cout << endl;
}
 
// Function to find the weight of subtree
int findWeight(struct node* root)
{
    // If the root node is null
    // then weight of subtree will be 0
    if (root == NULL)
        return 0;
     
    return root->weight +
        findWeight(root->left)
        + findWeight(root->right);
}
 
// Function to compute new level
// of the nodes based on the
// difference of weight K
void changeLevels(struct node* root, int k)
{
 
    if (root == NULL)
        return;
     
    // Change the level of root node
    root->level = root->level + k;
 
    // Recursively change the level of
    // left and right subtree
    changeLevels(root->left, k);
    changeLevels(root->right, k);
}
 
// Function to calculate weight of
// the left and the right subtrees and
// adjust levels based on their difference
void adjustLevels(struct node* root)
{
 
    // No adjustment required
    // when root is null
    if (root == NULL)
        return;
 
    // Find weights of left
    // and right subtrees
    int w_left = findWeight(root->left);
    int w_right = findWeight(root->right);
 
    // find the difference between the
    // weights of left and right subtree
    int w_diff = w_left - w_right;
 
    // Change the levels of nodes
    // according to weight difference at root
    changeLevels(root->left, -w_diff);
    changeLevels(root->right, w_diff);
 
    // Recursively adjust the levels
    // for left and right subtrees
    adjustLevels(root->left);
    adjustLevels(root->right);
}
 
// Driver code
int main()
{
    // Number of levels
    int N = 3;
 
    // Number of nodes
    int nodes = pow(2, N) - 1;
 
    vector weights;
    // Vector to store weights of tree nodes
    for (int i = 1; i <= nodes; i++) {
        weights.push_back(i);
    }
     
    vector levels;
    // Vector to store levels of every nodes
    for (int i = 0; i < N; i++) {
 
        // 2^i nodes are present at ith level
        for (int j = 0; j < pow(2, i); j++) {
 
            // value of level becomes negative
            // while going down the root
            levels.push_back(-1 * i);
        }
    }
     
    // Create tree with the
// given weights and levels
    struct node* root
= createTree(weights, levels);
     
    // Adjust the levels
    adjustLevels(root);
     
    // Display the final levels
    printNodeLevels(root);
     
    return 0;
}


输出:
// Java Program to print updated levels
// of each node of a Complete Binary Tree
// based on difference in weights of subtrees
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
 
class GFG {
 
    // Node for the given binary tree
    static class node {
 
        int weight;
 
        // stores the weight of node
        int level;
 
        // stores the level of node
        node left;
        node right;
        public node(int w, int l)
        {
            this.weight = w;
            this.level = l;
            left = right = null;
        }
    }
 
    // Utility function to insert a node
    // in a tree rooted at root
    static node insert(node root, int n_weight, int n_level, Queue q)
    {
        node n = new node(n_weight, n_level);
 
        // if the tree is empty till now
        // make node n the root
        if (root == null)
            root = n;
 
        // If the frontmost node of
        // queue has no left child
        // make node n its left child
        // the frontmost node still
        // remains in the queue because
        // its right child isnull yet
        else if (q.peek().left == null)
        {
            q.peek().left = n;
        }
 
        // Make node n the right child of
        // the frontmost node and remove
        // the front node from queue
        else
        {
            q.peek().right = n;
            q.poll();
        }
       
        // push the node n into queue
        q.add(n);
 
        return root;
    }
 
    // Function to create a complete binary tree
    static node createTree(ArrayList weights,
                           ArrayList levels)
    {
 
        // initialise the root node of tree
        node root = null;
 
        // initialise a queue of nodes
        Queue q = new LinkedList<>();
        int n = weights.size();
        for (int i = 0; i < n; i++)
        {
 
            /*
             * keep inserting nodes with weight values
             * from the weights vector and level
             * values from the levels vector
             */
            root = insert(root, weights.get(i), levels.get(i), q);
        }
        return root;
    }
 
    // Function to print final levels of nodes
    static void printNodeLevels(node root)
    {
 
        if (root == null)
            return;
 
        Queue q = new LinkedList<>();
        q.add(root);
 
        while (!q.isEmpty()) {
            System.out.print(q.peek().level + " ");
 
            if (q.peek().left != null)
                q.add(q.peek().left);
            if (q.peek().right != null)
                q.add(q.peek().right);
            q.poll();
        }
        System.out.println();
    }
 
    // Function to find the weight of subtree
    static int findWeight(node root)
    {
 
        // If the root node isnull
        // then weight of subtree will be 0
        if (root == null)
            return 0;
 
        return root.weight + findWeight(root.left) + findWeight(root.right);
    }
 
    // Function to compute new level
    // of the nodes based on the
    // difference of weight K
    static void changeLevels(node root, int k)
    {
        if (root == null)
            return;
 
        // Change the level of root node
        root.level = root.level + k;
 
        // Recursively change the level of
        // left and right subtree
        changeLevels(root.left, k);
        changeLevels(root.right, k);
    }
 
    // Function to calculate weight of
    // the left and the right subtrees and
    // adjust levels based on their difference
    static void adjustLevels(node root)
    {
 
        // No adjustment required
        // when root isnull
        if (root == null)
            return;
 
        // Find weights of left
        // and right subtrees
        int w_left = findWeight(root.left);
        int w_right = findWeight(root.right);
 
        // find the difference between the
        // weights of left and right subtree
        int w_diff = w_left - w_right;
 
        // Change the levels of nodes
        // according to weight difference at root
        changeLevels(root.left, -w_diff);
        changeLevels(root.right, w_diff);
 
        // Recursively adjust the levels
        // for left and right subtrees
        adjustLevels(root.left);
        adjustLevels(root.right);
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Number of levels
        int N = 3;
 
        // Number of nodes
        int nodes = (int) Math.pow(2, N) - 1;
 
        // Vector to store weights of tree nodes
        ArrayList weights = new ArrayList<>();
        for (int i = 1; i <= nodes; i++) {
            weights.add(i);
        }
 
        // Vector to store levels of every nodes
        ArrayList levels = new ArrayList<>();
        for (int i = 0; i < N; i++) {
 
            // 2^i nodes are present at ith level
            for (int j = 0; j < (int) Math.pow(2, i); j++) {
 
                // value of level becomes negative
                // while going down the root
                levels.add(-1 * i);
            }
        }
 
        // Create tree with the
        // given weights and levels
        node root = createTree(weights, levels);
 
        // Adjust the levels
        adjustLevels(root);
 
        // Display the final levels
        printNodeLevels(root);
 
    }
}
 
// This code is contributed by sanjeev2552