【问题标题】:In C++ can I create a Binary Search Tree using objects/structs as the node?在 C++ 中,我可以使用对象/结构作为节点创建二叉搜索树吗?
【发布时间】:2022-08-02 23:22:36
【问题描述】:

在其他相关的 c++ 工作中,我设法创建了一种二叉搜索树模板。这里的含义是,使用这个模板,我可以为各种数据类型创建一个 BST……Int、string 等等。我被要求使用 BST 作为数据结构。让我们想象一下它的天气数据。测量设备每天记录几次温度,所以我有日期和时间以及温度。每条记录我想使用一个结构作为容器,所以我想要这样的东西:

struct Record 
{
string DateTime;
float temperature;
};

DateTime 在这里是一个字符串,因为它的格式类似于 dd/mm/yyyy xx:xx。也许我可以将其转换为 int。

有数千条记录,我想将它们全部插入我的 BST。这是行不通的,我的 BST 模板不知道如何比较 2 条记录来判断哪一条将进入左链接和右链接。我可以只写一个布尔运算符 > 函数,它将接受 2 条记录,比较两者的日期时间,然后说稍后制作的记录是否“大于”早先制作的记录,因此它会进入树中,依此类推?这一般会起作用吗?

我是否应该做一些事情,比如创建一个名为 DateTime 的 int 与记录配对的地图,然后将代表 DateTimes 的所有整数值插入到我的 BST 中。然后当我需要取回我的数据时,首先我搜索 BST 以检查是否有条目,然后将结果用于我的地图,然后它应该给我我想要的对象。

我需要做这一切的原因是因为我想执行诸如“给我 2018 年每个月的平均温度”之类的计算。然后我会搜索我的 BST 以将 2018 年每个月的所有日期时间返回给我,然后通过地图访问我的记录以计算温度并取平均值。

请随时指出我正确的方向。我发现谷歌搜索如何创建对象和结构的 BST 给了我使用整数节点的 BST 实现,这还不够……?

  • \“在 C++ 中,我可以使用对象/结构作为节点创建二叉搜索树吗?\” - 简短回答:是的。
  • 使用operator < 进行比较更常见,您应该编写BST 以这种方式使用比较。所以a > b 宁愿写成b < a。您可以向 BST 添加额外的模板参数 auto compare 并将其用于比较。您也可以将其默认为std::less,这样它将成为可选的,如果BST 的数据类型有一个,则使用operator <
  • 您不应该将 Record 结构转换为 int 以插入到 BST 中。这就是您将BST 设为模板的原因,这样您就不必做那样的事情了。它应该只是一个BST<Record>。如果您还将lower_boundupper_bound 实现为与en.cppreference.com/w/cpp/algorithm/upper_bound 中的第二个版本匹配的模板函数,那么从2018 年累积所有Records 变得微不足道。

标签: c++ binary-search-tree


【解决方案1】:

DateTime 在这里是一个字符串,因为它的格式类似于 dd/mm/yyyy xx:xx。也许我可以将其转换为 int。

你可以。

我可以只写一个布尔运算符> 函数,它需要 2 条记录,比较两者的日期时间,然后说稍后制作的记录是否“大于”早先制作的记录,因此它会进入树中,依此类推?这一般会起作用吗?

是的,它会的。

我是否应该做一些事情,比如创建一个名为 DateTime 的 int 与记录配对的地图

这是一种可能性,尽管它不应该是分离数据结构。 BST 中的一个节点将由 int 键入,并将关联记录作为有效负载(因此 struct 带有 intRecord)。或者,如果空间效率是一个问题,您可以将int 与温度(再次作为struct)配对。然后定义一个可以将int 转换回日期字符串的函数。

另一种选择是将 DateTime 字符串格式更改为 ISO 8601 format:yyyy-mm-ddThh:mm:ss,然后在资源您的数据,因此不需要来回转换。

这有两个优点:

  • 这是一个很好的标准,受到许多服务/库/API 的支持
  • 词汇顺序是您期望的日期/时间顺序。这意味着您不再需要转换为 int,而是可以将记录用作 BST 中的节点,只需将日期与字符串比较进行比较。

【讨论】:

    【解决方案2】:

    正如 trincot 所指出的,有很多方法可以使用具有结构的二叉搜索树。我牢记我不应该使用单独的结构来存储我的记录,因为他们正确地指出,使用我的 BST 模板通常应该将其声明为 BST<Record> 而不是 BST<int>。

    在我之前的示例中,我使用了一个结构来存储 Record 数据。我决定改用一个类。在我的新 Record 类中,我添加了运算符函数,以便我的 BST 模板在比较 2 个对象时知道要做什么。

    想象一下,我的新 Record 类看起来像这样:

    class Record
    {
        public:
            /* 
            member variables
            */
            void printValues();
            bool operator>(const LogNode& otherLogNode) const;
            bool operator==(const LogNode& otherLogNode) const;
    };
    
    ostream & operator<<(ostream &out, const LogNode &LT);
    //implementation below
    bool LogNode::operator>(const LogNode& otherLogNode) const
    {
        return (date > otherLogNode.date);
    }
    
    bool LogNode::operator==(const LogNode& otherLogNode) const
    {
        return (date == otherLogNode.date);
    }
    

    如您所见,我重载了 > 和 == 运算符。例如,在我的模板中,使用这些运算符的函数如下所示(这只是其中的一个用于说明的函数):

    template<class T>
    void BSTTemplate<T>::insert(const T& insertItem)
    {
        Node<T>* current;
        Node<T>* trailCurrent;
        Node<T>* newNode;
    
        newNode = new Node<T>;
        newNode->info = insertItem;
        newNode->leftLink = nullptr;
        newNode->rightLink = nullptr;
    
        if (root == nullptr)
            root = newNode;
        else
        {
            current = root;
            while (current != nullptr)
            {
                trailCurrent = current;
                if(current->info == insertItem)
                {
                    cout << "Item is already in tree. Duplicates not allowed." << endl;
                    return;
                }
                else if(current->info > insertItem)
                    current = current->leftLink;
                else
                    current = current->rightLink;
    
            }
            if (trailCurrent->info > insertItem)
                trailCurrent->leftLink = newNode;
            else
                trailCurrent->rightLink = newNode;
        }
    }// end insert()
    

    如果没有重载的运算符,语句如

    if(current->info == insertItem)
    

    else if(current->info > insertItem)
    

    不适用于我希望创建和使用的对象。

    其他用户建议我输入一个帮助我解决问题的答案,所以你去吧!希望对其他人有所帮助...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2018-10-16
      • 2021-07-12
      相关资源
      最近更新 更多