2016-02-22 71 views
0

這是我的Binarysearchtree.h。當必須刪除的元素有一個子元素時,remove函數不起作用。從二叉搜索樹中刪除元素

#ifndef BINARYSEARCHTREE_H_INCLUDED 
#define BINARYSEARCHTREE_H_INCLUDED 

class BinarySearchTreeNode { 
    public: 
    int data; 
    BinarySearchTreeNode* left; 
    BinarySearchTreeNode* right; 

    BinarySearchTreeNode(int data):data(data), left(NULL), right(NULL) { 
    } 


    ~BinarySearchTreeNode() { 
     if (left) 
      delete left; 
     if (right) 
      delete right; 
    } 
    friend class BinarySearchTree; 
}; 

class BinarySearchTree 
{ 
    private: 
    int size; 

    public: 
    BinarySearchTreeNode * root; 

    BinarySearchTree() 
    { 
     size=0; 
     root= NULL; 
    } 

    private: 
    void insert_help(BinarySearchTreeNode*root,BinarySearchTreeNode*node) 
    { 
     if(root==NULL) 
      { 
       this->root=node; 
       return; 
      } 

     if(node->data>root->data and root->right==NULL) 
       { 
        root->right=node; 
        return; 
       } 
      if(node->data<=root->data and root->left==NULL) 
       { 
        root->left=node; 
        return; 
       } 

     if(node->data<=root->data) 
      insert_help(root->left,node); 
     if(node->data>root->data) 
      insert_help(root->right,node); 




    } 


    public: 
    void insert(int data) 
    { 
     BinarySearchTreeNode* newnode=new BinarySearchTreeNode(data); 
     size++; 
     insert_help(this->root,newnode); 

    } 

    void printLevelWise() 
{ 
    if(root==NULL) 
     return; 

    queue<BinarySearchTreeNode*> pending; 
    pending.push(root); 
    while(pending.empty()!=1) 
    { 
     BinarySearchTreeNode*latest=pending.front(); 
     pending.pop(); 
     cout<<latest->data<<": "; 
     if(latest->left) 
     { 
      cout<<latest->left->data<<","; 
     pending.push(latest->left); 
     } 
     if(latest->right) 
     { 
      cout<<latest->right->data<<","; 
      pending.push(latest->right); 
     } 
     cout<<"\n"; 
    } 
} 


bool isEmpty() 
{ 
    if(root==NULL) 
     return true; 
    else 
     return false; 
} 

int Size() 
{ 
    return size; 
} 

    private: 
     BinarySearchTreeNode* Search_help(BinarySearchTreeNode*root,int data) 
     { 
      if(root==NULL or root->data==data) 
     return root; 

    if(data>root->data) 
     return Search_help(root->right,data); 
    if(data <= root->data) 
     return Search_help(root->left,data); 



     } 



public: 

BinarySearchTreeNode* Search(int data) 
{ 
    return Search_help(root,data); 


} 
private: 

BinarySearchTreeNode*return_min(BinarySearchTreeNode*root) 
{ 
    if(root->left==NULL) 
     return root; 
    return return_min(root->left); 
} 

/*this is my remove function*/ 
BinarySearchTreeNode* remove_help(BinarySearchTreeNode*root,int data) 

{ 
    if(root==NULL) 
     return root; 

    if(data>root->data) 
     root->right= remove_help(root->right,data); 

    else if(data<root->data) 
     root->left=remove_help(root->left,data); 

    else 
    { 
     //no child 
     if(root->left==NULL and root->right==NULL) 
     { 
      delete root; 
      return NULL; 
     } 
     //one child 
     if(root->left==NULL) 
     { 
      BinarySearchTreeNode*temp=root->right; 

      delete root; // when i remove this line the code works idk why 
      return temp; 

     } 
     if(root->right==NULL) 
     { 
      BinarySearchTreeNode*temp=root->left; 
      delete root; 
      return temp; 

     } 
     //more than one child 

     BinarySearchTreeNode*temp=return_min(root->right); 
     root->data=temp->data; 
     root->right=remove_help(root->right,temp->data); 



    } 

    return root; 
    } 

public: 
void Remove(int data) 
{ 
    root=remove_help(root,data); 
    return; 

} 

}; 

#endif // BINARYSEARCHTREE_H_INCLUDED 
//////////////////////////////// 

該程序適用於當節點沒有孩子或多於兩個孩子但沒有一個孩子時。

/*here is my main program*/ 

#include<iostream> 
#include"tree.h" 
#include<limits.h> 
#include<math.h> 
#include<stack> 
#include"BinaryTree.h" 
#include"linked_list.h" 
#include<vector> 
#include"BinarySearchTree.h" 
using namespace std; 

int main() 
{ 
BinarySearchTree bst; 
bst.insert(6); 
bst.insert(3); 
bst.insert(9); 
bst.insert(4); 
bst.insert(8); 
bst.printLevelWise(); 

bst.Remove(9); 

bst.printLevelWise(); 

} 

/我不知道,就像我的問題需要評論更多的上下文/

回答

0

這裏是代碼我寫了一段時間前從二叉搜索樹中刪除C節點++:

基本上,如果您要刪除沒有子節點的節點,只需在刪除它之前將父節點指針設置爲空。十分簡單。

如果節點有子節點,我們需要將這些子節點鏈接到我們正在刪除的節點的父節點 - 這有點難度。

如果我們刪除根節點,在刪除它之前給它一個假的父節點,並將其與其中一個子節點交換。

/////////////////////////////// 
// DeleteID Function: 
/////////////////////////////// 
bool Tree::deleteID(int id) { 
    if(root == NULL) 
     return false; 
    Node *toDelete = findNode(id);  //Find the node to delete 
    if(toDelete == NULL)    //If we can't find it, return false 
     return false; 
    Node *parent = findParent(id);  //Find the parent of the node to delete 
    Node *justInCase;     //In case we are deleting the root node 
    bool deletingRoot = false;   //This is a special case so handle it differently 
    if(root->id == id) {    //If we're deleting the root node 
     justInCase = new Node();  //Let's create a fake parent for the root 
     justInCase->leftChild = root; //Just to make sure that we can run checks on parents 
     justInCase->rightChild = NULL; 
     justInCase->id = 0;    //Later on in the code 
     parent = justInCase;   //Set the parent of the root to our new fake node 
     deletingRoot = true;   //Let the end of our function know we're deleting the root 
    } 
    bool deletingLeftChild = (parent->leftChild == toDelete); 
    if(toDelete->leftChild == NULL && toDelete->rightChild == NULL) { 
     if(toDelete == root) 
      root = NULL; 
     if(deletingLeftChild) 
      parent->leftChild = NULL; 
     else 
      parent->rightChild = NULL; 
     delete toDelete; 
     return true; 
    } 
    if((toDelete->leftChild == NULL || toDelete->rightChild == NULL) && (parent != NULL && !deletingRoot)) { 
     if(deletingLeftChild) 
      parent->leftChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild; 
     else 
      parent->rightChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild; 
     delete toDelete; 
     return true; 
    } 
    Node *replacer = findMaximum(toDelete->leftChild);   //Replace the node we're deleting with the hightest LEFT Child 
    if(replacer == NULL || replacer == toDelete)    //If we can't find a left child (in case of deleting root) 
     replacer = findMinimum(toDelete->rightChild);   //Find the smallest RIGHT child 
    Node *replacerParent = findParent(replacer->id);   //Find the parent of this child 
    if(replacerParent != NULL) {        //If this child has a parent 
     if(replacerParent->leftChild == replacer) {    //If the child is to the left of the parent 
      if(replacer->leftChild != NULL)      //And the left child has a child of its own (in case of findMinimum/maximum) 
       replacerParent->leftChild = replacer->leftChild;//set the parent's child to this child's node 
      else 
       replacerParent->leftChild = NULL;    //Otherwise, set the parent's child to NULL 
     } 
     else {             //In the case of Right Child 
      if(replacer->rightChild != NULL)     //Do the same thing 
       replacerParent->rightChild = replacer->rightChild; 
      else 
       replacerParent->rightChild = NULL; 
     } 
    } 
    toDelete->id = replacer->id;        //Swap the IDs of the nodes we're deleting 
    delete replacer;           //And delete the minimum or maximum that we found 
    return true; 
} 

完整的解決方案:

https://stackoverflow.com/a/10084855/1274820