簡體   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