从给定权重构建一个没有相邻节点权重相同的 N 元树


N 元树是数据结构和算法 (DSA) 中具有许多子节点的基本分层结构。构建一个 N 元树,其限制条件是没有任何两个相邻节点具有相同的权重,这是一项有趣的工作。本文研究了一种系统的方法,可以从一组权重构建这样的树。我们将深入探讨此任务所需的基本数据结构和算法,提供一个全面的指南来实践该解决方案。由于这种独特的树结构在调度、决策和优化等领域的多种应用,它在 DSA 中是一个关键概念。

使用的方法

  • 深度优先搜索 (DFS) 方法

  • 广度优先搜索 (BFS) 方法

深度优先搜索 (DFS) 方法

DFS 方法使用深度优先搜索算法遍历给定的权重集合来构建 N 元树。在遍历过程中,我们向节点添加权重,确保没有两个相邻节点具有相同的权重。此方法使用递归来有效地遍历权重并构建树。

算法

  • 将给定集合中的权重按降序排序。

  • 为一个空的 N 元树创建一个根节点,其权重为排序集合中的最小权重。

  • 创建一个 DFS 函数,它有两个输入:当前节点和下一个要应用的权重的索引。

  • 在 DFS 函数中,检查当前节点的权重是否与其父节点或任何已存在的子节点的权重相同。如果是,则跳过此权重,转到下一个权重。

  • 为当前节点分配当前权重。

  • 为当前节点的每个子节点递归调用 DFS 函数,并将下一个权重的索引作为参数传递。

示例

#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;
}

输出

Tree weights in descending order: 50 40 

广度优先搜索 (BFS) 方法

使用 BFS 方法构建 N 元树时,使用广度优先搜索算法遍历给定的权重集合。与 DFS 方法类似,我们在遍历过程中仔细选择并分配权重,以确保相邻节点具有不同的权重。

算法

  • 将给定集合中的权重按降序排序。

  • 为一个空的 N 元树创建一个根节点,其权重为排序集合中的最小权重。

  • 使用根节点创建 BFS 队列。

  • 当 BFS 队列仍然活动时,将队首节点出队,并从排序集合中应用下一个权重。

  • 检查当前节点的权重是否与其任何已存在的子节点或父节点(如果存在)的权重相同。如果是,则跳过此权重,转到下一个权重。

  • 为当前节点创建子节点并将它们添加到 BFS 队列。

  • 重复步骤 4 到 6,直到所有权重都被用尽。

示例

#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;
}

输出

/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:

结论

构建一个没有相邻节点具有相同权重的 N 元树是一个有趣的问题,可以使用数据结构和算法来解决。通过使用一种系统的方法,包括排序和迭代分配,我们可以构建一个独特的树结构,在任务调度、数据组织、决策和优化中具有多种应用。当我们探索数据结构和算法的迷人世界时,理解这个概念使我们能够为现实世界的问题构建有效的解决方案,在这些问题中,在 N 元树中保持独特的权重至关重要。

更新于:2023年8月4日

75 次浏览

开启您的职业生涯

完成课程后获得认证

开始学习
广告
© . All rights reserved.