繁体   English   中英

在 C++ 中,我可以使用对象/结构作为节点创建二叉搜索树吗?

[英]In C++ can I create a Binary Search Tree using objects/structs as the node?

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

struct Record 
{
string DateTime;
float temperature;
};

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

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

我是否应该创建一个 map 与一个名为 DateTime 的 int 与记录配对,然后将代表 DateTimes 的所有 integer 值插入我的 BST。 然后当我需要取回我的数据时,首先我搜索 BST 以检查是否有条目,然后使用该结果对我的 map,然后它应该给我我想要的 object。

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

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

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

你可以。

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

是的,它会的。

我是否应该做一些类似创建一个 map 的事情,其中一个名为 DateTime 的 int 与记录配对

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

另一种选择是将 DateTime 字符串格式更改为ISO 8601 格式:yyyy-mm-ddThh:mm:ss,并在数据处执行此操作,因此不需要来回转换。

这有两个优点:

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

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

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

想象一下,我的新记录 class 看起来像这样:

class Record
{
    public:
        /* 
        member variables
        */
        void printValues();
        bool operator>(const Record& otherRecord) const;
        bool operator==(const Record& otherRecord) const;
};

ostream & operator<<(ostream &out, const Record &REC);
//implementation below
bool Record::operator>(const Record& otherRecord) const
{
    return (date > otherRecord.date);
}

bool Record::operator==(const Record& otherRecord) const
{
    return (date == otherRecord.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)

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

其他用户告诉我,我应该输入一个帮助我解决问题的答案,所以你有 go。 希望对其他人有所帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM