使用 BST 内的模板进行运算符重载

发布于 2024-10-19 01:52:35 字数 3323 浏览 0 评论 0原文

我目前有一个二叉搜索树设置,利用模板可以轻松更改二叉搜索树中的数据类型。目前,我在重载包含要存储在树中的数据的 StudentRecord 类时遇到问题。我需要重载此类中的比较运算符,以便我的 BST 可以根据两个对象的内容之一(在本例中为学生 ID)正确比较两个对象。然而,尽管在 StudentRecord 中重载了运算符,但仍然没有进行正确的比较。

详细信息如下:

目前,bst 对象studentTree 已创建,类型为

bst<studentRecord *> studentTree;

studentRecord 的类如下:

// studentRecord class
class studentRecord{
public:
    // standard constructors and destructors
    studentRecord(int studentID, string lastName, string firstName, string academicYear){ // constructor
        this->studentID=studentID;
        this->lastName=lastName;
        this->firstName=firstName;
        this->academicYear=academicYear;
    }

    friend bool operator > (studentRecord &record1, studentRecord &record2){
        if (record1.studentID > record2.studentID)
            cout << "Greater!" << endl;
        else
            cout << "Less then!" << endl;
        return (record1.studentID > record2.studentID);
    }

private:
    // student information
    string studentID;
    string lastName;
    string firstName;
    string academicYear;
};

每当将新项目添加到我的BST 中时,必须将它们相互比较。因此,我想重载studentRecord类,以便当这个比较过程发生时,对studentID进行比较(否则,将进行无效比较)。

但是,我的插入函数从不使用重载的比较函数。相反,它似乎以其他方式比较两个对象,导致 BST 内的排序无效。我的插入函数的一部分如下——重要的是要注意,由于模板化过程的发生,toInsert 和nodePtr->data 都应该是studentRecord 类型。

// insert (private recursive function)
template<typename bstType>
void bst<bstType>::insert(bstType & toInsert, bstNodePtr & nodePtr){
    // check to see if the nodePtr is null, if it is, we've found our insertion point (base case)
    if (nodePtr == NULL){
        nodePtr = new bst<bstType>::bstNode(toInsert);
    }

    // else, we are going to need to keep searching (recursive case)
    // we perform this operation recursively, to allow for rotations (if AVL tree support is enabled)
    // check for left
    else if (toInsert < (nodePtr->data)){ // go to the left (item is smaller)
        // perform recursive insert
        insert(toInsert,nodePtr->left);

        // AVL tree sorting
        if(getNodeHeight(nodePtr->left) - getNodeHeight(nodePtr->right) == 2 && AVLEnabled)
            if (toInsert < nodePtr->left->data)
                rotateWithLeftChild(nodePtr);
            else
                doubleRotateWithLeftChild(nodePtr);
    }

另外,这是 BST 类定义的一部分,

// BST class w/ templates
template <typename bstType>
class bst{

private: // private data members

    // BST node structure (inline class)
    class bstNode{
    public: // public components in bstNode

        // data members
        bstType data;
        bstNode* left;
        bstNode* right;

        // balancing information
        int height;

        // constructor
        bstNode(bstType item){
            left = NULL;
            right = NULL;
            data = item;
            height = 0;
        }

        // destructor
        // no special destructor is required for bstNode     
    };

    // BST node pointer
    typedef bstNode* bstNodePtr;

public: // public functions.....

您对可能导致这种情况的原因有什么想法吗?我是否重载了错误的类或错误的函数?任何帮助都是值得赞赏的——我似乎迷失了方向,因为有很多不同的事情同时发生。

I currently have a binary search tree setup, utilizing templates to allow me to easily change the type of data within the binary search tree. At the moment, I'm having trouble overloading the studentRecord class which contains the data to be stored in the tree. I need to overload the comparison operators within this class, so that my BST can properly compare two objects based on one of their contents (in this case, the student ID). However, despite overloading the operators within studentRecord, proper comparisons are still not occurring.

Details below:

At the moment, the bst object studentTree has been created, of type

bst<studentRecord *> studentTree;

studentRecord is the following class:

// studentRecord class
class studentRecord{
public:
    // standard constructors and destructors
    studentRecord(int studentID, string lastName, string firstName, string academicYear){ // constructor
        this->studentID=studentID;
        this->lastName=lastName;
        this->firstName=firstName;
        this->academicYear=academicYear;
    }

    friend bool operator > (studentRecord &record1, studentRecord &record2){
        if (record1.studentID > record2.studentID)
            cout << "Greater!" << endl;
        else
            cout << "Less then!" << endl;
        return (record1.studentID > record2.studentID);
    }

private:
    // student information
    string studentID;
    string lastName;
    string firstName;
    string academicYear;
};

Whenever new items are added to my BST, they must be compared with each other. Hence, I wanted to overload the studentRecord class, so that when this comparison process occurs, the studentIDs are compared (as otherwise, an invalid comparison will be made).

However, my insertion function never uses my overloaded comparison functions. Instead, it seems to be comparing the two objects some other way, resulting in invalid sorting within the BST. Part of my insert function is below -- it is important to note that both toInsert and nodePtr->data should be of type studentRecord, due to the templating process occuring.

// insert (private recursive function)
template<typename bstType>
void bst<bstType>::insert(bstType & toInsert, bstNodePtr & nodePtr){
    // check to see if the nodePtr is null, if it is, we've found our insertion point (base case)
    if (nodePtr == NULL){
        nodePtr = new bst<bstType>::bstNode(toInsert);
    }

    // else, we are going to need to keep searching (recursive case)
    // we perform this operation recursively, to allow for rotations (if AVL tree support is enabled)
    // check for left
    else if (toInsert < (nodePtr->data)){ // go to the left (item is smaller)
        // perform recursive insert
        insert(toInsert,nodePtr->left);

        // AVL tree sorting
        if(getNodeHeight(nodePtr->left) - getNodeHeight(nodePtr->right) == 2 && AVLEnabled)
            if (toInsert < nodePtr->left->data)
                rotateWithLeftChild(nodePtr);
            else
                doubleRotateWithLeftChild(nodePtr);
    }

Also, here is a portion of the BST class defintion

// BST class w/ templates
template <typename bstType>
class bst{

private: // private data members

    // BST node structure (inline class)
    class bstNode{
    public: // public components in bstNode

        // data members
        bstType data;
        bstNode* left;
        bstNode* right;

        // balancing information
        int height;

        // constructor
        bstNode(bstType item){
            left = NULL;
            right = NULL;
            data = item;
            height = 0;
        }

        // destructor
        // no special destructor is required for bstNode     
    };

    // BST node pointer
    typedef bstNode* bstNodePtr;

public: // public functions.....

Any ideas on what may be causing this? Am I overloading the wrong class or the wrong function? Any help is appreciated -- I seem to be getting lost since so many different things are occurring at once.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南风起 2024-10-26 01:52:35

你像这样实例化你的模板类:

bst<studentRecord *> studentTree;

所以 bstType == StudentRecord*

然后插入看起来像这样:

template<studentRecord*>
void bst<studentRecord*>::insert(studentRecord*& toInsert, bst<studentRecord*>::bstNodePtr & nodePtr);

所以你正在做一个指针比较,这就是为什么你的运算符没有被调用,正如 Asha allready 指出的那样。

更重要的是,您仅重载大于运算符(>),但在插入中使用小于运算符(<)。如果您真的要在插入中比较两个 StudentRecord 类型的对象,则代码甚至不应该编译,并且应该抱怨它无法找到合适的小于运算符。

更重要的是,我可以指出您的代码中的几个问题:

  1. studentRecord.studentID 是字符串类型吗?但是,您尝试在构造函数中为其分配一个整数。这将简单地将整数转换为字符并将字符分配给字符串 - 所以很可能不是您想要的。
  2. 您缺少小于运算符。

下面的代码和一些代码演示了在比较 StudentRecord 类型的两个实例时调用该运算符。您还可以通过注释 StudentRecord 类中的运算符定义来了解缺少小于运算符的影响(-> 编译错误)。

class studentRecord
{
public:

    studentRecord(int studentID) : studentID(studentID)
    { 
    }

    bool operator > (studentRecord &record)
    {
        return (studentID > record.studentID);
    }

    /* Uncomment to get rid of the compile error!
    bool operator < (studentRecord &record)
    {
        return studentID < record.studentID;
    }
    */

private:
    // student information
    int studentID;
};

int main()
{
    studentRecord r1(10);
    studentRecord r2(5);

    if ( r1 < r2 )
    {
        cout << "It works! " << "r1 less than r2" << endl;
    }
    else
    {
        cout << "It works! " << "r1 greater than r2" << endl;
    }

    if ( r1 > r2 )
    {
        cout << "It works! " << "r1 greater than r2" << endl;
    }
    else
    {
        cout << "It works! " << "r1 less than r2" << endl;
    }
}

作为结束评论,提供其他比较运算符可能是个好主意(>=、<=、== 和 !=。

You instantiate your template class like this:

bst<studentRecord *> studentTree;

So bstType == studentRecord*

The insert looks like this then:

template<studentRecord*>
void bst<studentRecord*>::insert(studentRecord*& toInsert, bst<studentRecord*>::bstNodePtr & nodePtr);

so you are doing a pointer comparison and this is why your operator is not called as Asha allready pointed out.

More so you overload only the greater than operator (>) but in insert you use the less than operator (<). If you would really compare two objects of type studentRecord in insert the code should't even compile and should complain that it is unable to find an appropriate less than operator.

More so I can point out several problems in your code:

  1. studentRecord.studentID is of type string? However you try to assign it an integer in the constructor. This will simply convert the integer to char and assign the character to the string - so quite probably not what you intended.
  2. You are missing the less than operator.

Below you code and some thest code that demonstrates the operator gets called when comparing two instances of type studentRecord. You can also see what would be the effects of the missing less than operator by commenting the operator definition in the studentRecord class (-> compile error).

class studentRecord
{
public:

    studentRecord(int studentID) : studentID(studentID)
    { 
    }

    bool operator > (studentRecord &record)
    {
        return (studentID > record.studentID);
    }

    /* Uncomment to get rid of the compile error!
    bool operator < (studentRecord &record)
    {
        return studentID < record.studentID;
    }
    */

private:
    // student information
    int studentID;
};

int main()
{
    studentRecord r1(10);
    studentRecord r2(5);

    if ( r1 < r2 )
    {
        cout << "It works! " << "r1 less than r2" << endl;
    }
    else
    {
        cout << "It works! " << "r1 greater than r2" << endl;
    }

    if ( r1 > r2 )
    {
        cout << "It works! " << "r1 greater than r2" << endl;
    }
    else
    {
        cout << "It works! " << "r1 less than r2" << endl;
    }
}

As an ending comment probably it would be a good idea to provide the other comparison operators too ( >=, <=, == and !=.

独夜无伴 2024-10-26 01:52:35

你的树是一棵指针树。因此,当您尝试将元素插入树中时,将比较指针的值。所以你的重载运算符不会被调用。如果您想使用重载运算符,那么您应该创建 bst

Your tree is a tree of pointers. So when you try to insert an element into the tree the values of the pointers is compared. So your overloaded operator is not called. If you want to use the overloaded operator then you should create bst<studentrecord>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文