【问题标题】:How to increment the value whenever I find the key? BST每当我找到密钥时如何增加值? BST
【发布时间】:2020-07-22 21:53:15
【问题描述】:

我能够从文本文件中检索所有单词并将它们放入树中,但每当我在树中找到数据时,我无法将出现次数加一。 每个单词现在显示一次,但出现 1 时不会增加。

这是我的班级节点

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

【问题讨论】:

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


【解决方案1】:

当具有指定数据的节点已经存在于二叉树中时,成员函数Insert发生内存泄漏,因为在这段代码中sn-p

    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;
}

【讨论】:

  • 老板你做得很好。 THAAAANKKSSS 我怎样才能像这样提高自己?
  • @KingAzaiez 尝试在 SO 的其他问题中描述的作业很有用。
  • 弗拉德先生,我感激不尽。我已经被困在这两天了,你甚至没有使用 find 功能就做到了。
  • @KingAzaiez 函数 find 在这种情况下没有用,因为它使函数 Insert 效率低下。
  • 我会听取您的建议,并将我在这里找到的问题作为改进作业。非常感谢弗拉德先生
【解决方案2】:

您需要使getOcc() 返回一个引用,以便您可以更新该值。目前,您正在增加事件的副本。

试试

Node.h

int &getOcc();

Node.cpp

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

并像这样使用它

int &h = n->getOcc();
++h;

【讨论】:

  • else if (find(n-&gt;getData()) == true){ 对我来说似乎是错误的。请尝试else if (find(num)) {
  • 还是一样 1,我在这里卡了2天:'(
  • 你试过调试你的 find 方法吗?我会从那里开始看看到底会发生什么。
  • 另一个问题是你总是增加根节点而不是你真正想要的那个
  • 现在希望得到问题 xD 在插入时,您总是在创建一个新节点。然后,您在新创建的对象上递增,而不是在树中的对象上递增。所以你应该重新设计你的 find 方法来返回一个 Node*。如果找到它应该返回匹配节点,否则返回 nullptr。然后您可以增加发生次数
猜你喜欢
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
相关资源
最近更新 更多