zoukankan      html  css  js  c++  java
  • 二叉搜索树的搜索和插入与删除算法优化

    代码是根据之前的二叉树模板修改来的,删去了非递归遍历,加入二叉搜索树的搜索、插入和删除,实现方法在73~153行

      1 #include<iostream>
      2 #include<stack>
      3 #include<queue>
      4 using namespace std;
      5 template <class T> class BinaryTree;
      6 template <class T>
      7 class BinaryTreeNode
      8 {
      9     friend class BinaryTree<T>;
     10 private:
     11     T data; //二叉树数据域
     12     BinaryTreeNode *leftchild; //左孩子指针
     13     BinaryTreeNode *rightchild; //右孩子指针
     14 public:
     15     BinaryTreeNode(){leftchild=rightchild=NULL;}
     16     BinaryTreeNode(const T elem)
     17     {
     18         data=elem;
     19         leftchild=rightchild=NULL;
     20     }
     21     BinaryTreeNode(const T elem,BinaryTreeNode<T> *l,BinaryTreeNode<T> *r)
     22     {
     23         data=elem;
     24         leftchild=l;
     25         rightchild=r;
     26     }
     27     BinaryTreeNode<T> * left() const{return leftchild;}
     28     BinaryTreeNode<T> * right() const{return rightchild;}
     29     void setLeft(BinaryTreeNode *l){leftchild=l;}
     30     void setRight(BinaryTreeNode *r){rightchild=r;}
     31     void setValue(const T value){data=value;}
     32     T Value(){return data;}
     33     bool isLeaf()
     34     {
     35         if(leftchild==NULL&&rightchild==NULL)
     36             return true;
     37         else
     38             return false;
     39     }
     40     BinaryTreeNode<T>& operator = (const BinaryTreeNode<T> &Node)
     41     {
     42         cout << "=" ;
     43         data=Node.data;
     44         leftchild=Node.leftchild;
     45         rightchild=Node.leftchild;
     46         return *this;
     47     }
     48 };
     49 template <class T>
     50 class BinaryTree
     51 {
     52 private:
     53     BinaryTreeNode<T> *root;
     54     void setRoot(BinaryTreeNode<T> *r){root=r;}
     55 public:
     56     BinaryTree(){root=NULL;}
     57     bool isEmpty() const
     58     {
     59         if(root==NULL)
     60             return true;
     61         return false;
     62     };
     63     BinaryTreeNode<T> * Root(){return root;}
     64     BinaryTreeNode<T> * Parent(BinaryTreeNode<T> *current);
     65     BinaryTreeNode<T> * LeftSibling(BinaryTreeNode<T> *current);
     66     BinaryTreeNode<T> * RightSibling(BinaryTreeNode<T> *current);
     67     void CreatTree(const T &info,BinaryTree<T> &left,BinaryTree<T> &right);
     68     void PreOrder(BinaryTreeNode<T> *root);
     69     void InOrder(BinaryTreeNode<T> *root);
     70     void PostOrder(BinaryTreeNode<T> *root);
     71     void LevelOrder(BinaryTreeNode<T> *root);
     72     void deleteBinaryTree(BinaryTreeNode<T> *root);
     73     void InsertNode(BinaryTreeNode<T> *root,BinaryTreeNode<T> *newpointer)
     74     {
     75         BinaryTreeNode<T> *pointer=NULL;
     76         if(root==NULL)//根节点为空,直接插入
     77         {
     78             setRoot(newpointer);
     79             return;
     80         }
     81         else pointer=root;
     82         while(pointer!=NULL)
     83         {
     84             if(newpointer->Value()==pointer->Value())
     85                 return;
     86             else if((newpointer->Value())<(pointer->Value()))
     87             {
     88                 if(pointer->left()==NULL)
     89                 {
     90                     pointer->setLeft(newpointer);
     91                     return;
     92                 }
     93                 else
     94                     pointer=pointer->left();
     95             }
     96             else
     97             {
     98                 if(pointer->right()==NULL)
     99                 {
    100                     pointer->setRight(newpointer);
    101                     return;
    102                 }
    103                 else pointer=pointer->right();
    104             }
    105         }
    106     }
    107     void DeleteNodeEx(BinaryTreeNode<T> *pointer)
    108     {
    109         //优化的搜索二叉树删除算法
    110         //若待删结点有左子树,则寻找左子树中最大的结点,将此结点的左子树挂接到其父节点的右子树上
    111         //将待删结点替换成左子树中最大的结点,删除待删结点
    112         if(pointer==NULL)return;
    113         BinaryTreeNode<T> *temppointer;
    114         BinaryTreeNode<T> *tempparent=NULL;
    115         BinaryTreeNode<T> *parent=Parent(pointer);
    116         if(pointer->left()==NULL)
    117             temppointer=pointer->right();
    118         else{
    119             temppointer=pointer->left();
    120             while(temppointer->right()!=NULL)
    121             {
    122                 tempparent=temppointer;
    123                 temppointer=temppointer->right();
    124             }
    125             if(tempparent==NULL)
    126                 pointer->setLeft(temppointer->left());
    127             else tempparent->setRight(temppointer->left());
    128             temppointer->setLeft(pointer->left());
    129             temppointer->setRight(pointer->right());
    130         }
    131         if(parent==NULL)root=temppointer;
    132         else if((parent->left())==pointer)parent->setLeft(temppointer);
    133         else parent->setRight(temppointer);
    134         delete pointer;
    135         pointer=NULL;
    136         return;
    137     }
    138     BinaryTreeNode<T> * Find(const T value)
    139     {
    140         if(root==NULL)return NULL;
    141         BinaryTreeNode<T> *p;
    142         p=root;
    143         while(p!=NULL&&(p->Value())!=value)
    144         {
    145             if((p->Value())>value)
    146                 p=p->left();
    147             else p=p->right();
    148         }
    149         if((p->Value())==value)return p;
    150         cout << "non-exist" <<endl;
    151         return NULL;
    152     }
    153 };
    154 template <class T>
    155 class StackElem{
    156 public:
    157     BinaryTreeNode<T> *pointer;
    158     int tag;
    159 };
    160 template <class T>
    161 BinaryTreeNode<T> * BinaryTree<T>::Parent(BinaryTreeNode<T> *current) //返回当前结点的父结点
    162 {
    163     using std::stack;
    164     stack<BinaryTreeNode<T> *> aStack; //使用栈存放未访问右子树的结点
    165     BinaryTreeNode<T> *pointer=root;
    166     if(root!=NULL&&current!=NULL)
    167     {
    168         while(!aStack.empty()||pointer!=NULL)
    169         {
    170             if(pointer!=NULL)
    171             {
    172                 if(current==pointer->left()||current==pointer->right())
    173                     return pointer;
    174                 aStack.push(pointer);
    175                 pointer=pointer->left();
    176             }
    177             else
    178             {
    179                 pointer=aStack.top();
    180                 aStack.pop();
    181                 pointer=pointer->right();
    182             }
    183         }
    184         return NULL;
    185     }
    186     else
    187         return NULL;
    188 }
    189 template <class T>
    190 BinaryTreeNode<T> * BinaryTree<T>::LeftSibling(BinaryTreeNode<T> *current) //返回当前节点左兄弟
    191 {
    192     using std::stack;
    193     stack<BinaryTreeNode<T> *>aStack;
    194     BinaryTreeNode<T> *pointer=root;
    195     if(root!=NULL&&current!=NULL)
    196     {
    197         while(!aStack.empty()||pointer!=NULL)
    198         {
    199             if(pointer!=NULL)
    200             {
    201                 if(current==pointer->right()&&(pointer->left())!=NULL)
    202                     return pointer->left();
    203                 aStack.push(pointer);
    204                 aStack.pop();
    205                 pointer=pointer->left();
    206             }
    207             else
    208             {
    209                 pointer=aStack.top();
    210                 aStack.pop();
    211                 pointer=pointer->right();
    212             }
    213         }
    214         return NULL;
    215     }
    216     else
    217         return NULL;
    218 }
    219 template <class T>
    220 BinaryTreeNode<T> * BinaryTree<T>::RightSibling(BinaryTreeNode<T> *current) //返回当前节点右兄弟
    221 {
    222     using std::stack;
    223     stack<BinaryTreeNode<T> *>aStack;
    224     BinaryTreeNode<T> *pointer=root;
    225     if(root!=NULL&&current!=NULL)
    226     {
    227         while(!aStack.empty()||pointer!=NULL)
    228         {
    229             if(pointer!=NULL)
    230             {
    231                 if(current==pointer->left()&&(pointer->right())!=NULL)
    232                     return pointer->right();
    233                 aStack.push(pointer);
    234                 aStack.pop();
    235                 pointer=pointer->left();
    236             }
    237             else
    238             {
    239                 pointer=aStack.top();
    240                 aStack.pop();
    241                 pointer=pointer->right();
    242             }
    243         }
    244         return NULL;
    245     }
    246     else
    247         return NULL;
    248 }
    249 template <class T>
    250 void BinaryTree<T>::CreatTree(const T &info,BinaryTree<T> &left,BinaryTree<T> &right) //创建树
    251 {
    252     root=new BinaryTreeNode<T>(info,left.root,right.root);
    253     left.root=right.root=NULL;
    254 }
    255 template <class T>
    256 void BinaryTree<T>::PreOrder(BinaryTreeNode<T> *root) //先序遍历
    257 {
    258     if(root!=NULL)
    259         visit(root);
    260     else
    261         return;
    262     PreOrder(root->left());
    263     PreOrder(root->right());
    264 }
    265 template <class T>
    266 void BinaryTree<T>::InOrder(BinaryTreeNode<T> *root) //中序遍历
    267 {
    268     if(root==NULL)
    269         return;
    270     InOrder(root->left());
    271     visit(root);
    272     InOrder(root->right());
    273 }
    274 template <class T>
    275 void BinaryTree<T>::PostOrder(BinaryTreeNode<T> *root) //后序遍历
    276 {
    277     if(root==NULL)
    278         return;
    279     PostOrder(root->left());
    280     PostOrder(root->right());
    281     visit(root);
    282 }
    283 template <class T>
    284 void BinaryTree<T>::LevelOrder(BinaryTreeNode<T> *root) //层次遍历
    285 {
    286     using std::queue;
    287     queue<BinaryTreeNode<T> *> aQueue;
    288     BinaryTreeNode<T> *p=root,*q;
    289     aQueue.push(p);
    290     while(!aQueue.empty())
    291     {
    292         p=aQueue.front();
    293         aQueue.pop();
    294         visit(p);
    295         q=p;
    296         if((p->left())!=NULL)
    297         {
    298             q=p->left();
    299             aQueue.push(q);
    300         }
    301         if((p->right())!=NULL)
    302         {
    303             q=p->right();
    304             aQueue.push(q);
    305         }
    306     }
    307 }
    308 template <class T>
    309 void BinaryTree<T>::deleteBinaryTree(BinaryTreeNode<T> *root) //删除以root为根节点的树
    310 {
    311     if(root==NULL)return;
    312     deleteBinaryTree(root->left());
    313     deleteBinaryTree(root->right());
    314     delete root;
    315     root=NULL;
    316 }
    317 
    318 void visit(BinaryTreeNode<int> *Root) //访问结点元素
    319 {
    320     if(Root!=NULL)
    321         cout << Root->Value() <<" ";
    322 }
    323 int main()
    324 {
    325     BinaryTreeNode<int> *p;
    326     BinaryTreeNode<int> e(10);
    327     BinaryTree<int> a,b,c;
    328     int n,s,l=1;
    329     cout << "Enter the number of node" <<endl;
    330     while(cin>>n)
    331     {
    332         for(int i=0;i<n;i++)
    333         {
    334             cin>>s;
    335             p=new BinaryTreeNode<int>(s);
    336             a.InsertNode(a.Root(),p);
    337         }
    338         a.InOrder(a.Root());
    339         cout <<endl;
    340         a.PreOrder(a.Root());
    341         cout <<endl;
    342         a.LevelOrder(a.Root());
    343         cout <<endl;
    344         cin>>l;
    345         cout << "Enter the number of delete node" <<endl;
    346         for(int i=0;i<l;i++)
    347         {
    348             cin>>s;
    349             p=a.Find(s);
    350             if(p!=NULL)
    351             {
    352                 a.DeleteNodeEx(p);
    353                 a.InOrder(a.Root());
    354                 cout << endl;
    355                 a.PreOrder(a.Root());
    356                 cout <<endl;
    357                 a.LevelOrder(a.Root());
    358                 cout <<endl;
    359             }
    360         }
    361     }
    362     return 0;
    363 }
  • 相关阅读:
    JAVA中的除法运算
    虚拟内存的设置和相关问题的解决方法
    div + css + js 打造HTML的tab控件
    body居中 兼容ie和ff
    js 获取当前页面源代码
    windows系统的全部命令
    HR线条样式CSS定制
    PHP5.3.5以及Apache2.2.17安装简介
    如何使用apache在本地服务器虚拟域名来测试网站
    CakePHP常用技巧总结
  • 原文地址:https://www.cnblogs.com/LowBee/p/9023981.html
Copyright © 2011-2022 走看看