首页 文章

删除BST中的节点

提问于
浏览
0

我正在尝试删除BST . 我使用的算法是:

  • 如果搜索与一个节点匹配

1.1 . 如果有左子节点,则交换该节点及其左子节点的值 . 并再次调用左节点的功能 .

1.2 . 否则,如果没有左节点但是有正确的节点,则交换节点和右节点的值 . 调用右边节点的功能 .

1.3 . 如果没有左侧或右侧节点,请删除此节点 .

以下是类定义 .

class node{
  public:
  int value;
  node *left;
  node *right;
  node(){value=0; left=0; right =0;}
  node(int value){this -> value = value; left=0;right=0;}
  void print();
};

class tree{
  public:
  node *root;
  tree(){
    root = 0;
  }
  ~tree(){}
  void remove(node *, int);
  //tree(int value){root = &node(value);}
  void insert(int);
  void printSorted(node *);
  void printAll(node *);
};

print()函数打印出我是...,我的左孩子是......,我的右孩子是......

void node::print(){
  if(this == 0) return;
  cout<<"i am "<<value<<endl;
  if(left !=0){
    cout<<"i have left, left is "<<left -> value<<endl;
  }
  if(right !=0){
    cout<<"i have right, right is "<<right -> value <<endl;
  }
}

printAll()函数,从根遍历并按顺序打印 .

void tree::printAll(node *nodeP){
  if(nodeP == 0) return;
  else{
    node *iter = nodeP;
    if(iter -> left !=0){
      printAll(iter->left);
    }
    iter->print();
    cout<<endl;
    if(iter -> right !=0){
        printAll(iter -> right);
    }
  }
}

这是删除功能 .

void tree::remove(node* origin, int toDel){
  if(origin == 0) return;
  node *orig_origin = origin;
  int tmp;
  if(origin -> value == toDel){
    if((origin -> left == 0) && (origin -> right == 0)){
      delete origin;
      origin =0;
    }
    else if((origin -> left != 0) && (origin -> right == 0)){
      tmp = origin -> value;
      origin -> value = origin -> left -> value;
      origin -> left -> value = tmp;
      remove(origin -> left, toDel);
    }
    else if((origin -> left == 0) && (origin -> right != 0)){
      tmp = origin -> value;
      origin -> value = origin -> right -> value;
      origin -> right -> value = tmp;
      remove(origin -> right, toDel);
    }
    else{ 
      tmp = origin -> value;
      origin -> value = origin -> left -> value;
      origin -> left -> value = tmp;
      remove(origin -> left, toDel);
    }
  }
  else{
    if(origin -> value > toDel) remove(origin -> left, toDel);
    else remove(origin -> right, toDel);
  }
  origin = orig_origin;
}

我在调用删除后输入7 4 10 1 6 5,1在原始4位置 . 但是有一个0的孩子 . 所以不知怎的,我没有删除原来的1节点 .

sc-xterm-24:~/scratch/code/cpp_primer> ./a.out 
7 4 10 1 6 5 
i am 0

i am 1
i have left, left is 0
i have right, right is 6

i am 5

i am 6
i have left, left is 5

i am 7
i have left, left is 1
i have right, right is 10

i am 10

1 回答

  • 0

    当您've found the value in the tree, the handling of the last case (where there is both a left and right branch) is wrong. You can' t交换 origin->valueorigin->left->value 时,因为这会破坏树所需的排序 . 由于原始 origin->value 大于存储在左子树中的所有值,因此新 origin->left->value 将大于 origin->left->right 子树中存储的所有值 . 由于节点中的值应该小于存储在右侧树中的所有内容,因此将来对该分支的搜索可能会失败或找到错误的节点 .

相关问题