Construct an N-ary Tree having no Pair of Adjacent Nodes with Same Weight from given Weights


N-ary trees are fundamental hierarchical structures with numerous offspring in data structures and algorithms (DSA). It is an interesting task to build a N-ary tree with the restriction that no two adjacent nodes have the same weight. This article investigates a methodical method to build such a tree from a set of weights. We will go into the fundamental data structures and algorithms needed for this task, offering a thorough manual to put the answer into practice. This distinctive tree form is a key idea in DSA because of its numerous applications in fields including scheduling, decision-making, and optimization.

Methods Used

  • Depth-First Search (DFS) Approach

  • Breadth-First Search (BFS) Approach

Depth-First Search (DFS) Approach

The depth-first search technique is used in the DFS method to traverse the supplied set of weights while building the N-ary tree. We add weights to nodes throughout traversal, making sure that no two nearby nodes have the same weight. Recursion is used in this method to efficiently traverse the weights and build the tree.

Algorithm

  • Sort the weights in the supplied set in descending order.

  • Make a root node for an empty N-ary tree that has the sorted set's minimum weight.

  • Create a DFS function that has two inputs: the current node and the index of the following weight to be applied.

  • Check whether the weight of the current node matches that of its parent or any already-existing offspring within the DFS function. If so, move on to the following weight and omit this one.

  • Give the current node the current weight.

  • Recursively call the DFS function, passing the next weight's index as a parameter, for every child of the current node.

Example

#include <iostream>
#include <vector>
#include <algorithm>

struct Node {
   int weight;
   std::vector<Node*> children;
   
   Node(int w) : weight(w) {}
};

void DFS(Node* current, const std::vector<int>& weights, int& 
nextWeightIndex) {
   if (nextWeightIndex >= weights.size())
      return;

   for (Node* child : current->children) {
      if (child->weight == weights[nextWeightIndex])
         ++nextWeightIndex;
   }

   if (nextWeightIndex < weights.size()) {
      Node* newNode = new Node(weights[nextWeightIndex]);
      current->children.push_back(newNode);
      ++nextWeightIndex;
   }

   for (Node* child : current->children) {
      DFS(child, weights, nextWeightIndex);
   }
}

int main() {
   std::vector<int> weights = {50, 30, 40, 10, 20};
   std::sort(weights.begin(), weights.end(), std::greater<int>());
   
   Node* root = new Node(weights[0]);
   int nextWeightIndex = 1;
   
   DFS(root, weights, nextWeightIndex);
   std::cout << "Tree weights in descending order: ";
   std::cout << root->weight << " ";
   for (Node* child : root->children) {
      std::cout << child->weight << " ";
   }
   
   return 0;
}

Output

Tree weights in descending order: 50 40 

Breadth-First Search (BFS) Approach

When building the N-ary tree using the BFS method, the specified set of weights are traversed using a breadth-first search algorithm. We carefully choose and assign weights during the traversal to make sure that adjacent nodes have different weights, much like the DFS technique.

Algorithm

  • Sort the weights in the supplied set in descending order.

  • Make a root node for an empty N-ary tree that has the sorted set's minimum weight.

  • BFS queue creation using the root node.

  • Dequeue the front node and apply the subsequent weight from the sorted set to it while the BFS queue is still active.

  • The weight of the current node should match that of any existing children or its parent, if any. If so, move on to the following weight and omit this one.

  • For the current node, create offspring nodes and add them to the BFS queue.

  • In order to exhaust all weights, repeat steps 4 through 6.

Example

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

struct TreeNode {
   int weight;
   std::vector<TreeNode*> children;

   TreeNode(int w) : weight(w) {}
};

TreeNode* createRootNode(std::vector<int>& weights) {
   std::sort(weights.begin(), weights.end(), std::greater<int>());
   TreeNode* root = new TreeNode(weights.back());
   return root;
}

void createBFSQueue(TreeNode* root, std::queue<TreeNode*>& bfsQueue) {
   if (root == nullptr) return;

   bfsQueue.push(root);

   for (TreeNode* child : root->children) {
      createBFSQueue(child, bfsQueue);
   }
}

void applyWeightsAndCreateOffspring(TreeNode* node, std::vector<int>& weights) {
   if (node == nullptr || weights.empty()) return;

   std::vector<int> remainingWeights;

   for (int weight : weights) {
      if (node->weight != weight && std::find_if(node->children.begin(), node->children.end(),
         [weight](const TreeNode* child) { return child->weight == weight; }) == node->children.end()) {
         remainingWeights.push_back(weight);
      }
   }

   for (int weight : remainingWeights) {
      TreeNode* child = new TreeNode(weight);
      node->children.push_back(child);
      applyWeightsAndCreateOffspring(child, remainingWeights);
   }
}

int main() {
   std::vector<int> weights = {5, 2, 8, 3, 1};
   TreeNode* root = createRootNode(weights);
   std::queue<TreeNode*> bfsQueue;
   createBFSQueue(root, bfsQueue);

   while (!bfsQueue.empty()) {
      TreeNode* frontNode = bfsQueue.front();
      bfsQueue.pop();
      applyWeightsAndCreateOffspring(frontNode, weights);
   }

   std::queue<TreeNode*> printQueue;
   printQueue.push(root);
   while (!printQueue.empty()) {
      TreeNode* node = printQueue.front();
      printQueue.pop();
      std::cout << "Node Weight: " << node->weight << ", Children Weights: ";
      for (TreeNode* child : node->children) {
         std::cout << child->weight << " ";
         printQueue.push(child);
      }
      std::cout << std::endl;
   }

   return 0;
}

Output

/tmp/MNiyxGtrjS.o
Node Weight: 1, Children Weights: 8 5 3 2 
Node Weight: 8, Children Weights: 5 3 2 
Node Weight: 5, Children Weights: 8 3 2 
Node Weight: 3, Children Weights: 8 5 2 
Node Weight: 2, Children Weights: 8 5 3 
Node Weight: 5, Children Weights: 3 2 
Node Weight: 3, Children Weights: 5 2 
Node Weight: 2, Children Weights: 5 3 
Node Weight: 8, Children Weights: 3 2 
Node Weight: 3, Children Weights: 8 2 
Node Weight: 2, Children Weights: 8 3 
Node Weight: 8, Children Weights: 5 2 
Node Weight: 5, Children Weights: 8 2 
Node Weight: 2, Children Weights: 8 5 
Node Weight: 8, Children Weights: 5 3 
Node Weight: 5, Children Weights: 8 3 
Node Weight: 3, Children Weights: 8 5 
Node Weight: 3, Children Weights: 2 
Node Weight: 2, Children Weights: 3 
Node Weight: 5, Children Weights: 2 
Node Weight: 2, Children Weights: 5 
Node Weight: 5, Children Weights: 3 
Node Weight: 3, Children Weights: 5 
Node Weight: 3, Children Weights: 2 
Node Weight: 2, Children Weights: 3 
Node Weight: 8, Children Weights: 2 
Node Weight: 2, Children Weights: 8 
Node Weight: 8, Children Weights: 3 
Node Weight: 3, Children Weights: 8 
Node Weight: 5, Children Weights: 2 
Node Weight: 2, Children Weights: 5 
Node Weight: 8, Children Weights: 2 
Node Weight: 2, Children Weights: 8 
Node Weight: 8, Children Weights: 5 
Node Weight: 5, Children Weights: 8 
Node Weight: 5, Children Weights: 3 
Node Weight: 3, Children Weights: 5 
Node Weight: 8, Children Weights: 3 
Node Weight: 3, Children Weights: 8 
Node Weight: 8, Children Weights: 5 
Node Weight: 5, Children Weights: 8 
Node Weight: 2, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 2, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 2, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 2, Children Weights: 
Node Weight: 8, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 8, Children Weights: 
Node Weight: 2, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 2, Children Weights: 
Node Weight: 8, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 8, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 3, Children Weights: 
Node Weight: 8, Children Weights: 
Node Weight: 5, Children Weights: 
Node Weight: 8, Children Weights:

Conclusion

Using data structures and techniques, it is possible to construct a N-ary tree without any adjacent nodes having the same weight, which is an intriguing topic. We may develop a distinctive tree structure with diverse applications in task scheduling, data organization, decision-making, and optimization by using a systematic technique that involves sorting and iterative assignment. Understanding this idea enables us to build effective solutions to real-world problems where preserving unique weights inside a N-ary tree is crucial as we explore the interesting world of data structures and algorithms.

Updated on: 04-Aug-2023

59 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements