c++ - 每当我找到 key 时如何增加值? BST

标签 c++ tree insert binary-search-tree

我能够从文本文件中检索所有单词并将它们放在树中,只要在树中找到数据,我就无法将出现的次数增加一个。
现在每个单词显示一次,但出现1,不会增加。
这是我的类(class)节点

class Node{

    private:
        Node *left;                     //left child
        Node *right;                    //right child
        std::string num;
    public:
        int data;                       //number
        Node();                         //constructor
        void setData(string num, int data);         //sets number in node
        string getData();                   //return numbers from node
        int getOcc();
        void setLeft(Node *l);          //sets left child pointer
        Node* getLeft();                //returns left child pointer
        void setRight(Node *r);         //sets right child pointer
        Node* getRight();               //return right child pointer
};
Node::Node(){
    this->left = NULL;
    this->right = NULL;
}


void Node::setData(string num, int data){
    this->num = num;
    this->data = data;
}


string Node::getData(){
    return this->num;
}

int Node::getOcc(){
    return this->data;
}


void Node::setLeft(Node *l){
    this->left = l;
}

Node* Node::getLeft(){
    return this->left;
}

void Node::setRight(Node *r){
    this->right = r;
}

Node* Node::getRight(){
    return this->right;
}
这是我类的BST
class BST{

    private:
        Node * root;        //root node pointer

    public:
        BST();                                  //constructor
        ~BST();                                 //destructor
        void Insert(string num, int data);                  //Inserts new number in tree
        bool find(string num);                      //finds whether a number is present in tree
        void min();                             //find and print minimum number in the tree
        void max();                             //find and print maximum number in the tree
        void save_file(string filename);        //save the tree to file
        void Delete(string num);                    //deletes a number from tree
        void LoadFromFile(string filename);     //loads numbers from file to tree
        void Print();                           //print tree to stdout


        //private functions used as helper functions in the public operations
    private:
        void printHelper(Node *root);
        bool findHelper(Node *root,string num);
        void InsertHelper(Node* current, Node* newnode);
        void findMinHelper(Node* current);
        void findMaxHelper(Node * current);
        void saveHelper(ofstream &fout, Node* current);
        Node* DeleteHelper(Node *current, string num);
        Node * findMaximum(Node * n);
        void clear(Node *currnt);
};

BST::BST(){
    this->root = NULL;      //root is NULL in the start
}

BST::~BST(){
    clear(root);            //delete all nodes
}


void BST::clear(Node* current){
    if(current == NULL)
        return;

    clear(current->getLeft());          //clear left subtree
    clear(current->getRight());         //clear right subtree
    delete current;                     //delete this node
}


void BST::Insert(string num, int data){

    //create new node to be inserted
    Node *n = new Node();
    n->setData(num, data);
    n->setLeft(NULL);
    n->setRight(NULL);


    if(this->root == NULL)      //if root is null, simply add at root
        root = n;


////////// IN HERE, I TRIED TO INCREMENT INCREMENTATION THE OCCURENCE BY 1
    else if (find(n->getData()) == true){
        int h = n->getOcc();
        h++;
        n->setData(num, h);
    }
    else
        InsertHelper(root,n);   //call helper to insert
}


void BST::InsertHelper(Node* current, Node* newnode){
    if(current == NULL)
        return;

    //node should be inserted at right subtree
    if(current->getData() <= newnode->getData()){

        //if no node at right
        if(current->getRight() == NULL )
            current->setRight(newnode);     //add at right node

        else
            InsertHelper(current->getRight(), newnode);     //insert in right subtree
    }
    else{

        if(current->getLeft() == NULL){         //if no node at left
            current->setLeft(newnode);          //add at left
        }else{
            InsertHelper(current->getLeft(), newnode);      //insert in left subtree
        }
    }
}


bool BST::find(string num){
    return findHelper(root,num);
}


bool BST::findHelper(Node *current,string num){
    if(current == NULL)
        return false;

    if(current->getData() == num)       //if number is found
        return true;

    if(num < current->getData())        //if number is less than current node
        return findHelper(current->getLeft(),num);      //go to left tree
    else
        return findHelper(current->getRight(),num);     //go to right tree
}


void BST::min(){
    findMinHelper(root);
}

void BST::findMinHelper(Node* current){
    if(current == NULL)
        return;

    if(current->getLeft() == NULL)          //if no node at right
        cout<<current->getData();           //current has min data
    else
        findMinHelper(current->getLeft());  //check on left subtree
}

void BST::max(){
    findMaxHelper(root);
}

void BST::findMaxHelper(Node * current){
    if(current == NULL)
        return;

    if(current->getRight() == NULL)             //if no node at right
        cout<<current->getData();               //current node has max data
    else
        findMaxHelper(current->getRight());     //check on right subtree
}



void BST::Print(){
    printHelper(root);
}

void BST::printHelper(Node *current){
    if(current == NULL)     //stop if NULL
        return;

    printHelper(current->getLeft());        //print left tree
    cout<<current->getData() << " " << current->getOcc() << " ";        //print current node data
    printHelper(current->getRight());       //print right tree
}

void BST::Delete(string num){
    root = DeleteHelper(root,num);
}

Node* BST::DeleteHelper(Node *current, string num){
    if(current == NULL)
        return NULL;

    Node *tobeReturned;

    if (current->getData() == num) {          //if key is found

        if (current->getLeft() == NULL) {        //no node at left

            tobeReturned = current->getRight();
            delete current;
            return tobeReturned;          //right subtree should replace this node

        } else if (current->getRight() == NULL) {

            tobeReturned = current->getLeft();
            delete current;
            return tobeReturned;
        } else {

            //find maximum node in the left subtree
            Node * maxnode = findMaximum(current->getLeft());

            //copy values from max node to this node
            //      current->setData(maxnode->getData());

            //delete the max node
            current->setLeft(DeleteHelper(current->getLeft(), num));
        }
        cout<<"Deleted!!!";
    } else {        //not found
        if (num < current->getData()) {
            current->setLeft(DeleteHelper(current->getLeft(),num));
        } else {
            current->setRight(DeleteHelper(current->getRight(), num));
        }
    }
    return current;
}

Node* BST::findMaximum(Node * n){
    if(n->getRight() == NULL)       //if no node at right, current is maximum
        return n;
    return findMaximum(n->getRight());      //find in right subtree
}

在我的主要语言中,我使用出现次数为= 1的循环逐个插入单词tree.Insert(s,1); ,但最终结果始终是每个单词的出现次数= 1

最佳答案

当具有指定数据的节点在二进制树中已经存在时,成员函数Insert会发生内存泄漏,因为在此代码段中

    else if (find(n->getData()) == true){
        int h = n->getOcc();
        h++;
        n->setData(num, h);
    }
它没有被释放。而且,成员函数setData应用于此新创建的节点,该节点与二叉树的现有节点没有任何共同点。
该函数及其辅助函数InsertHelper可以通过以下方式重写
void BST::Insert(string num, int data)
{
    InsertHelper( root, num, data );   //call helper to insert
}
void BST::InsertHelper( Node * &current, string num, int data )
{
    if ( current == nullptr )
    {
        // create new node to be inserted
        current = new Node();
        current->setData( num, data );
        current->setLeft( nullptr );
        current->setRight( nullptr );
    }
    else if ( num < current->getData() )
    {
        InsertHelper( current.getLeft(), num, data );
    }
    else if ( current->getData() < num )
    {
        InsertHelper( current.getRight(), num, data );
    }
    else
    {
        int h = current->getOcc();
        h++;
        current->setData(num, h);
    }
}       
为了使功能起作用,这两个功能也要改变
Node * & getLeft();

Node * & Node::getLeft(){
    return this->left;
}
Node * & Node::getRight();

Node * & Node::getRight(){
    return this->right;
}

关于c++ - 每当我找到 key 时如何增加值? BST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63043741/

相关文章:

c++ - 我是否需要遍历两个子树进行计算,从根到叶的总和,到给定值?

algorithm - 二叉树中最低层所有叶节点的总和

python - MySQLdb 将字典插入表中

iphone - 如何将数据插入 iPhone 中的 SQLite 数据库

c++ - eclipse cdt 相对包含路径?

java - VS2015 - 在 Android 项目中引用 .so 文件

c++ - 无法在ubuntu中编译opencv程序

c++ - 使用c++11的std::thread,什么时候修改全局变量是线程安全的?

c++ - 红黑树插入,我想我可能把旋转弄乱了

sql - 将大量数据加载到 Oracle SQL 数据库