1. 程式人生 > >c++二叉排排序樹的實現 補上了刪除和查詢操作

c++二叉排排序樹的實現 補上了刪除和查詢操作

#include <iostream>
#include<stack>
using namespace std;
class node{
    friend class tree;
public:
    node* left;
    int data;
    node* right;
    node* parent;
};
class tree{
public:
    node* root;
    tree(){
    root=NULL;
    }
    void insertBtree(int elem);
    void inorder(tree* T);
    node* find_min(node* N);
    node* search_node(tree* T,int elem);
    void deletBtree(tree* T,int elem);
    void transparent(tree*T,node *u,node *v);
};
void tree::insertBtree(int elem){
    node* newNode=new node();
    newNode->data=elem;
    newNode->left=newNode->right=NULL;
    if(root==NULL){
        root=newNode;
        root->parent=NULL;
    }
    else{
      node* cur=root;
      node* par;
      while(cur!=NULL){
        par=cur;
        if(cur->data>elem) cur=cur->left;
        else cur=cur->right;
      }
      if(par->data>elem){par->left=newNode;newNode->parent=par;}
      else {
            par->right=newNode;
            newNode->parent=par;
      }
    }
}
void tree::inorder(tree* T){//中序遍歷
    stack<node*> s;
    node* cur=T->root;
    while(cur!=NULL||s.size()!=0){//向左側走
          while(cur!=NULL){
            s.push(cur);
            cur=cur->left;
          }
          if(s.size()!=0){//棧不空,訪問棧頂,如果有右孩子,右孩子進棧,繼續下一輪尋棧左孩子的迴圈
           cout<<s.top()->data;
            node* r=s.top();
            s.pop();
            if(r->right) s.push(r->right);
          }
    }
}
node* tree::find_min(node* N){
    node *cur=N->right;
    while(cur->left!=NULL){
        cur=cur->left;
    }
    return cur;
}
node* tree::search_node(tree* T,int elem){
    node *cur=T->root;
    while(cur->data!=elem&&cur!=NULL){
        if(cur->data>elem) cur=cur->left;
        else if(cur->data<elem) cur=cur->right;
    }
    return cur;
}
void tree::transparent(tree *T,node *u,node *v){//以一棵以V為根的子樹替換一棵以U為根的子樹
    if(u->parent==NULL) //u是樹根
        T->root=v;
    else if(u==u->left)
        u->parent->left=v;
    else u->parent->right=v;
    if (v!=NULL)
        v->parent=u->parent;
}
void tree::deletBtree(tree* T,int elem){
    node* cur=search_node(T,elem);
    node *del,*s;
    if(cur!=NULL){
       if(cur->left==NULL){//左子樹為空,把右子樹接到父節點上
        transparent(T,cur,cur->right);
       }
       else if(cur->right==NULL){//右子樹為空,把左子樹接到父節點上
        transparent(T,cur,cur->left);
       }
       else {
        del=find_min(cur);//左右子樹都存在,找到右子樹最小的節點(後繼節點)
        if(del->parent!=cur){//後繼節點不是刪除節點的右孩子
            transparent(T,del,del->right);
            del->right=cur->right;
            del->right->parent=del;
        }
        transparent(T,cur,del);//後繼節點是刪除節點的右孩子
        del->left=cur->left;
        del->left->parent=del;
       }
    }

}
int main(){
    tree* T=new tree();
    T->insertBtree(2);
    T->insertBtree(1);
    T->insertBtree(3);
    T->inorder(T);
    T->deletBtree(T,2);
    T->inorder(T);
}