如何在我的二叉搜索树中修复逻辑错误?

时间:2012-07-16 13:41:48

标签: c++ binary-search-tree

所以我一直试图让我的旧c ++二进制搜索树程序工作。它编译并运行但我没有得到我期望的结果。如果我按顺序插入c,d,a,b并尝试删除c,我的删除功能会跳过在顺序中找到的if条件。如果跳过条件限制,为什么还有其他2个?

它也是使用gcc编译的。

  Node::Node(string nodeItem,
           int nodeLine){
    item=nodeItem;
    vector<int> tempVector;
    tempVector.push_back(nodeLine);
    lines=tempVector;
    leftPtr = NULL;
    rightPtr = NULL;
}


// recursive method for finding node containing the word
Node* BST::find(string data, Node *curr) {

    if(curr==NULL) {
        cout << data << " is not in the tree" << endl;
        return curr;

    }
    if(curr->getItem().compare("theplaceholder")==0){
        return curr;
    }
    string tempItem = curr->getItem();
    //this if statement is if I am inserting a word that is already in the tree
    // or if I am removing the word from the tree
    if(data.compare(tempItem)==0){
        return curr;
    }
    else if(data.compare(tempItem)<0){
        return find(data,curr->getLeftPtr());
    }
    else{
        return find(data, curr->getRightPtr());
    }

}


void BST::insert(string data, int fromLine) {
    Node *curr;


    curr=find(data, root); 


    if(curr!=NULL && curr->getItem().compare("theplaceholder")==0){

        curr->setData(data);

        curr->addLines(fromLine);
    }


    if(curr==NULL){

        // I want to point to a nonNull node.
        // I am making a new node and having curr point to that instead of NULL
        //then I set it to



        curr=new Node(data, fromLine);


        cout <<curr->getItem() << endl;

        vector<int> foundLines=curr->getNodeLines();
        //cout<< "The word " <<curr->getItem() << " can be found in lines ";
        if(foundLines.empty())
            cout << "foundLines is empty";
        int size=foundLines.size();
        for(int count=0; count<size; count++){

            //cout << foundLines[count] << ", ";
        }

    }

    if(curr->getItem()==data){
        curr->addLines(fromLine);
    }
}
// remove method I am trying to check for in order successors to swap with the deleted node.
void BST::remove(string data) {
    Node *curr=root;


    Node *temp=find(data, curr);
    if(temp==NULL){
        cout << " nothing to remove" << endl;
    }
    else if(temp->getRightPtr()!=NULL){

        curr=temp->getRightPtr();
        cout << curr->getItem() << endl;
        while(curr->getLeftPtr()!=NULL){
            curr=curr->getLeftPtr();
            cout << curr->getItem() << endl;
        }
        temp->setData(curr->getItem());

        temp->setLines(curr->getNodeLines());
        delete curr;
        curr=NULL;
    }
    else if(temp->getLeftPtr()!=NULL){
        cout <<"if !temp->getLeftPtr" << endl;
        curr=temp->getLeftPtr();
        cout << curr->getItem() << endl;
        while(curr->getRightPtr()!=NULL){
            curr=curr->getRightPtr();
            cout << curr->getItem() << endl;
        }
        temp->setData(curr->getItem());

        temp->setLines(curr->getNodeLines());
        delete curr;
        curr=NULL;
    }
    else{
        cout <<"else delete temp" << endl;
        delete temp;
        temp=NULL;

    }

}

1 个答案:

答案 0 :(得分:0)

这条线的原因

else if(temp->getRightPtr()!=NULL){

永远不会成功,你永远不会在任何节点上设置正确的指针 - getRightPtr只能返回null。如果你在构建之后检查了调试器中树的状态,或者你通过插入函数,你可能已经看到了这一点。问题是:

  • 如果节点不在树中,你的find函数不返回null,而你的insert函数期望它将
  • 你的插入函数需要在树中找到该节点所在的位置 - 通过修复find函数或单独定位,然后创建一个新节点并从父节点添加对它的引用,适当的左侧或右侧
  • 你的插入函数显示第一个插入节点的行号两次:一次覆盖占位符时和插入结束时一次(而不是在这里使用占位符我可能已初始化root到为null,而是在创建第一个节点时设置root = curr)
  • 当从左侧分支推广最高节点时,您的删除功能需要做更多工作;它需要
    • 正确地从它的前一个父节点清理该节点 - 此时您删除了该对象但是只留下任何悬空指针
    • 在移动该节点之前提升该节点的所有子节点以获取其上一个插槽

      D                                       C                           
     / \                                     / \
    A   E  remove 'D'                       A   E
     \       => 'C' is highest on left       \
      C         but need to move B to C       B
     /
    B