【问题标题】:Generalization of tree creation树创建的概括
【发布时间】:2022-01-09 07:30:37
【问题描述】:

我想概括这个二叉树的创建过程,以便让不同类型的节点包含在树本身中。例如,我想让用户选择是用结构城市(如下所示)还是用结构 people 或他想在源代码中定义的任何结构来构建树。

有没有一种简单的方法来实现这些更改?

这是代码:

#include <iostream>

template <typename T>
struct node
{
    T infoStruct;
    // Pointers
    node* left = NULL;
    node* right = NULL;
};
struct city
{
    std::string cityName;
    int population;
};

struct people
{
    std::string name;
    std::string surname;
    int age;
    int weight;
};

node<city>* root;

void visualizeInOrder(node<city>*);
void insertNewNode(node<city>*, node<city>*);

int main()
{
    root = NULL;
    char choice;

    do
    {
        node<city>* tmp = new node<city>;
        std::cout << "Insert city name: ";
        getline(std::cin, tmp->infoStruct.cityName);
        std::cout << "Insert population: ";
        std::cin >> tmp->infoStruct.population;

        if (root)
            insertNewNode(root, tmp);
        else
            root = tmp;

        choice = 'N';
        std::cout << "Insert another city? [y|N]> ";
        std::cin >> choice;
        std::cin.ignore();
    } while (choice != 'N');

    visualizeInOrder(root);
}




void visualizeInOrder(node<city>* root)
{
    if (root->left) visualizeInOrder(root->left);
    std::cout << root->infoStruct.cityName << " has " << root->infoStruct.population << " population\n";
    if (root->right) visualizeInOrder(root->right);
}



void insertNewNode(node<city>* root, node<city>* leaf)
{
    if (root)
    {
        if (leaf->infoStruct.population < root->infoStruct.population)
            if (root->left)
                insertNewNode(root->left, leaf);
            else
                root->left = leaf;
        else
            if (root->right)
                insertNewNode(root->right, leaf);
            else
                root->right = leaf;
    }
}

【问题讨论】:

  • 首先要构建一个实际的二叉树,而不是简单地声明一个由main控制的节点类。
  • 让你的二叉树工作,首先没有模板。对数据使用固定数据类型,例如 int。在您的二叉树 {class} 工作后,使用 templates 仅更改数据类型。

标签: c++ templates struct tree generalization


【解决方案1】:

大部分作品已经存在。您可以做的第一步是简单地将insertNewNodevisualizeInOrder 的签名更改为接受node&lt;T&gt; 而不是node&lt;city&gt;


所以insertNewNode 会变成:

template<typename T>
void insertNewNode(node<T>* root, node<T>* leaf)
{
    if (root)
    {
        if (leaf->infoStruct.population < root->infoStruct.population)
            if (root->left)
                insertNewNode(root->left, leaf);
            else
                root->left = leaf;
        else
            if (root->right)
                insertNewNode(root->right, leaf);
            else
                root->right = leaf;
    }
}

但是,这里的问题是泛型类型T 不会有成员population。所以不要使用:

leaf->infoStruct.population < root->infoStruct.population

您可以在签名中添加模板比较函数Comp comp,然后使用它进行比较,并将其传递给递归调用:

template<typename T, typename Comp>
void insertNewNode(node<T>* root, node<T>* leaf, Comp comp)
{
    if (root)
    {
        if (comp(leaf.infoStruct, root.infoStruct)
            if (root->left)
                insertNewNode(root->left, leaf, comp);
            else
                root->left = leaf;
        else
            if (root->right)
                insertNewNode(root->right, leaf, comp);
            else
                root->right = leaf;
    }
}

但是,这不是添加比较函数的最有效方法,因为您总是必须手动在 main 中的第一次调用 insertNewNode 中添加一些函数,例如 lambda。因此,目前,您将在 main 中调用该函数,例如:

insertNewNode(root, tmp, [](const city& city_a, const city& city_b){
    return city_a.population < city_b.population;
});

这很冗长,如果population 是私人成员,它会直接不起作用。相反,您可以使用 std::less 作为默认值,因此声明将是:

template<typename T, typename Comp = std::less<>>
void insertNewNode(node<T>* root, node<T>* leaf, Comp comp = {});

现在您可以像我之前那样手动添加比较函数,也可以将operator&lt; 添加到您的city 类中,它会自动在insertNewNode 函数中使用:

struct city
{
     ⋮
    bool operator< (const city& other) const
    {
        return population < other.population;
    }
};

同样,对于visualizeInOrder,由于cityNamepopulationcity 独有的,因此您不能使用:

std::cout << root->infoStruct.cityName << " has " << root->infoStruct.population << " population\n";

相反,您可以为您的city 类重载ostream&amp; operator&lt;&lt; 以打印所有详细信息。而在visualizeInOrder 内部,它会变成:

std::cout << root->infoStruct << '\n';

【讨论】:

  • 非常感谢!这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 2017-05-06
  • 2017-05-11
  • 2019-12-20
相关资源
最近更新 更多