C++ AVL树节点遗漏了包含的结构的内容,我找不到原因

C++ AVL树节点遗漏了包含的结构的内容,我找不到原因,c++,C++,考虑以下AVL树实现。每个节点都包含一个数字列表。该键名为工作负荷,但将其视为一个简单的双变量。如果某个键等于已存在节点的键,则该数字将被推送到列表中。每次我从列表中弹出一个数字时,我都会执行一个检查,如果节点的列表为空->删除节点。但是,在key=3的元素被完全删除后,key=4的节点列表突然变为空。我已经试着解决它超过10个小时了,实际上这是我第一次需要在这里问一些问题。如果我错过了一些东西,请原谅 #include<iostream> #include <list>

考虑以下AVL树实现。每个节点都包含一个数字列表。该键名为工作负荷,但将其视为一个简单的双变量。如果某个键等于已存在节点的键,则该数字将被推送到列表中。每次我从列表中弹出一个数字时,我都会执行一个检查,如果节点的列表为空->删除节点。但是,在key=3的元素被完全删除后,key=4的节点列表突然变为空。我已经试着解决它超过10个小时了,实际上这是我第一次需要在这里问一些问题。如果我错过了一些东西,请原谅

#include<iostream> 
#include <list>
using namespace std;

class BST
{
    struct node
    {
        double workload;
        list<int> numbers;
        node* left;
        node* right;
        int height;
    };

    node* root;
    unsigned long long size;
    bool empty;

    void makeEmpty(node* t)
    {
        if(t == NULL)
            return;
        makeEmpty(t->left);
        makeEmpty(t->right);
        delete t;
    }

    node* insert(double workload,int number, node* t)
    {

        if(t == NULL)
        {
            t = new node;
            t->workload = workload;
            t->numbers.push_back(number);
            t->height = 0;
            t->left = t->right = NULL;
        }
        else if(t->workload == workload){
            t->numbers.push_back(number);
        }
        else if(workload < t->workload)
        {
            t->left = insert(workload, number, t->left);
            if(height(t->left) - height(t->right) == 2)
            {
                if(workload < t->left->workload)
                    t = singleRightRotate(t);
                else
                    t = doubleRightRotate(t);
            }
        }
        else if(workload > t->workload)
        {
            t->right = insert(workload, number, t->right);
            if(height(t->right) - height(t->left) == 2)
            {
                if(workload > t->right->workload)
                    t = singleLeftRotate(t);
                else
                    t = doubleLeftRotate(t);
            }
        }

        //if x == t->workload instead of using int workload. its a list and we push into it.
        t->height = max(height(t->left), height(t->right))+1;
        return t;
    }

    node* singleRightRotate(node* &t)
    {
        node* u = t->left;
        t->left = u->right;
        u->right = t;
        t->height = max(height(t->left), height(t->right))+1;
        u->height = max(height(u->left), t->height)+1;
        return u;
    }

    node* singleLeftRotate(node* &t)
    {
        node* u = t->right;
        t->right = u->left;
        u->left = t;
        t->height = max(height(t->left), height(t->right))+1;
        u->height = max(height(t->right), t->height)+1 ;
        return u;
    }

    node* doubleLeftRotate(node* &t)
    {
        t->right = singleRightRotate(t->right);
        return singleLeftRotate(t);
    }

    node* doubleRightRotate(node* &t)
    {
        t->left = singleLeftRotate(t->left);
        return singleRightRotate(t);
    }

    node* findMin(node* t)
    {
        if(t == NULL)
            return NULL;
        else if(t->left == NULL)
            return t;
        else
            return findMin(t->left);
    }

    node* findMax(node* t)
    {
        if(t == NULL)
            return NULL;
        else if(t->right == NULL)
            return t;
        else
            return findMax(t->right);
    }

    node* find(node* t,double workload){
        if (t->workload == workload){
            return t;
        }
        else if(workload < t->workload && t->left!=NULL)
            return find(t->left,workload);
        else if(workload > t->workload && t->right!=NULL)
            return find(t->right,workload);
        else{
            cout << "Null node encountered" << endl;
            return t;
        }
    }
    node* remove(double x, node* t)
    {
        node* temp;

        // Element not found
        if(t == NULL)
            return NULL;

        // Searching for element
        if(x < t->workload)
            t->left = remove(x, t->left);
        else if(x > t->workload)
            t->right = remove(x, t->right);

        // Element found
        // With 2 children
        else if(t->left && t->right)
        {
            temp = findMin(t->right);
            t->workload = temp->workload;
            t->right = remove(t->workload, t->right);
        }
        // With one or zero child
        else
        {
            temp = t;
            if(t->left == NULL)
                t = t->right;
            else if(t->right == NULL)
                t = t->left;
            delete temp;
        }
        if(t == NULL)
            return t;

        t->height = max(height(t->left), height(t->right))+1;

        // If node is unbalanced
        // If left node is deleted, right case
        if(height(t->left) - height(t->right) == -2)
        {
            // right right case
            if(height(t->right->right) - height(t->right->left) == 1)
                return singleLeftRotate(t);
            // right left case
            else
                return doubleLeftRotate(t);
        }
        // If right node is deleted, left case
        else if(height(t->right) - height(t->left) == 2)
        {
            // left left case
            if(height(t->left->left) - height(t->left->right) == 1){
                return singleRightRotate(t);
            }
            // left right case
            else
                return doubleRightRotate(t);
        }
        return t;
}



    int height(node* t)
    {
        return (t == NULL ? -1 : t->height);
    }

    int getBalance(node* t)
    {
        if(t == NULL)
            return 0;
        else
            return height(t->left) - height(t->right);
    }

    void inorder(node* t)
    {
        if(t == NULL)
            return;
        inorder(t->left);
        cout << t->workload<< " ";
        inorder(t->right);
    }

    //Reverse inorder (Sorted highest to lowest)
    void rinorder(node* t)
    {
        if(t == NULL)
            return;
        rinorder(t->right);
        cout << t->workload << " ";
        rinorder(t->left);
    }

    void preorder(node* t) 
    { 
        if (t == NULL) 
            return; 
        cout << t->workload << " "; 
        preorder(t->left);  
        preorder(t->right); 
    } 

    void postorder(node* t) 
    { 
        if (t == NULL) 
            return; 
        postorder(t->left);  
        postorder(t->right);
        cout << t->workload << " ";
    } 


public:
    BST()
    {
        root = NULL;
    }

    void insert(double workload, int number)
    {
        root = insert(workload, number, root);
    }

    void remove(double workload)
    {
        root = remove(workload, root);
    }

    void displayrin()
    {   
        cout << "Rinorder: ";
        rinorder(root);
        cout << endl;
    }

    void displayin()
    {   
        cout << "Inorder: ";
        inorder(root);
        cout << endl;
    }
        void displaypost()
    {
        cout << "Postorder: ";
        postorder(root);
        cout << endl;
    }
        void displaypre()
    {
        cout << "Preorder: ";
        preorder(root);
        cout << endl;
    }
    double getMax(){
        return findMax(root)->workload;
    }

    int getMaxNum(){
        return find(root,getMax())->numbers.front();
    }

    int getNum(double workload){
        return find(root,workload)->numbers.front();
    }

    //We pop a Num from a node
    void popnumber(double workload){
        node *t = find(root,workload);
            if(t!=NULL){
                if(!t->numbers.empty()){
                    t->numbers.pop_front();
                    //If the Num list of the node is empty, remove node
                    if(t->numbers.empty()){
                        remove(t->workload);
                    }
                }
            }

    }
};

int main()
{
    BST t;
    //key value pairs
    t.insert(2,1);
    t.insert(3,1);
    t.insert(3,2);
    t.insert(4,7);
    cout << t.getNum(4) << endl;
    cout << t.getNum(3)<<endl;
    t.popnumber(3);
    cout << t.getNum(3)<<endl;
    t.popnumber(3);
    t.displayin();
    t.displaypost();
    t.displaypre();
    t.displayrin();
    cout << t.getNum(4) << endl;
    cout << "The max is : " << t.getMax() << endl;
    cout << "The top Num of the Max is : " << t.getMaxNum() << endl;

    return 0;
}

正如评论中提到的,问题出在remove的“找到2个子元素”部分

要删除该元素,请在树中找到下一个元素。然后,您的实现希望复制找到的节点temp的内容。复制工作负载值,使t和temp具有相同的工作负载值4。您不能复制数字列表。t节点的工作负载为4,数字列表为空,而temp的工作负载为4,数字列表由一个元素7组成。然后删除临时文件,将丢失列表

一种修复方法是在将数字从树中删除之前,将数字从temp复制或移动到t。向节点添加MoveData方法,该方法将移动数据字段,同时不改变特定于树的字段,这将使添加新数据字段更容易


另一个修复方法是更改数据更新的方式。如果更新所有指针和其他与树相关的字段(如高度),则不必担心数据,任何指向节点的指针/迭代器都不会失效。

在比较双精度是否相等时,请务必小心。应该具有相同值的两个数字的计算结果并不总是相同的。请参阅以了解更多详细信息。感谢您的留言,我将继续努力。但是对于当前的示例,我不认为有任何不准确的情况发生。在插入所有节点后,使用调试器查看树的结构。它的构造正确吗?所有的高度都正确吗?如果是,那么使用它来查看删除第二个3节点时会发生什么。我没有看到在删除函数或由删除调用的任何函数中对数字进行任何操作。我先看看。是的,就是这样,你只是换了钥匙。您的3节点是空的,因此您将其键更改为4,删除了旧的4节点,然后查看现在标记为4的空节点,并说*我的4节点是如何变为空的?它的所有内容都到哪里去了?谢谢你的回答,以帮助他人的tl;dr fashion在“找到具有2个子元素的元素”处添加以下行:t->data=temp->data