二叉排序树的C++实现,包括难点删除

  1. #include <iostream>  
  2. using namespace std;  
  3. struct node{  
  4.     int num;  
  5.     node* Lnext;  
  6.     node* Rnext;  
  7. };  
  8. //建立二叉排序树  
  9. class list{  
  10. public:  
  11.     list();  
  12.     void node_insert();  
  13.     //p为要删除的节点,p0为删除节点的前一个节点,当然两节点可能重合  
  14.     //flag为标志位,0代表p0左节点与下一节点相连,1代表p0右节点域下一节点相连  
  15.     void node_delete(node* p,node* p0,bool flag);  
  16.     void mid_tranverse(node* p);  
  17.     void mid_print();  
  18.     void delete_place(int n);  
  19. private:  
  20.     node* head;  
  21. };  
  22. //n为要删除的数字大小  
  23. void list::delete_place(int n){  
  24.     node* p=head;  
  25.     node* p0=p;  
  26.     bool flag=0;  
  27.     while(p!=NULL){  
  28.         if(n<p->num){  
  29.             p0=p;  
  30.             p=p->Lnext;  
  31.             flag=0;  
  32.         }  
  33.         else if(n>p->num){  
  34.             p0=p;  
  35.             p=p->Rnext;  
  36.             flag=1;  
  37.         }  
  38.         else {  
  39.             node_delete(p,p0,flag);  
  40.             return;  
  41.         }  
  42.     }  
  43.     cout<<"抱歉,未找到您要删除的节点"<<endl;  
  44. }  
  45. //p对应要删除的数字n的地址  
  46. void list::node_delete(node *p,node* p0,bool flag){  
  47.     //情况1:叶子节点  
  48.     if(!(p->Lnext) && !(p->Rnext)){  
  49.         //如果p和p0不等  
  50.         if(p!=p0){  
  51.             free(p);  
  52.             p=NULL;  
  53.             if(!flag)  
  54.                 p0->Lnext=NULL;  
  55.             else  
  56.                 p0->Rnext=NULL;  
  57.         }  
  58.         //如果p和p0相等,那么说明p为根节点  
  59.         else{  
  60.             free(p);  
  61.             p=NULL;  
  62.         }  
  63.     }  
  64.     //情况2:p左节点为空  
  65.     else if(!(p->Lnext)){  
  66.         if(!flag)  
  67.             p0->Lnext=p->Rnext;  
  68.         else  
  69.             p0->Rnext=p->Rnext;  
  70.         free(p);  
  71.         p=NULL;  
  72.     }  
  73.     //情况3:p右节点为空  
  74.     else if(!(p->Rnext)){  
  75.         if(!flag)  
  76.             p0->Lnext=p->Lnext;  
  77.         else  
  78.             p0->Rnext=p->Lnext;  
  79.         free(p);  
  80.         p=NULL;  
  81.     }  
  82.     //情况4:p左右节点都不为空  
  83.     else{  
  84.         //合理利用p0,将p0变为要交换的节点  
  85.         node* temp=p;  
  86.         p0=p->Lnext;  
  87.         while(p0->Rnext!=NULL){  
  88.             temp=p0;  
  89.             p0=p0->Rnext;  
  90.         }  
  91.         p->num=p0->num;  
  92.         if(p0->Lnext==NULL){  
  93.             if(p==temp)  
  94.                 temp->Lnext=NULL;  
  95.             else  
  96.                 temp->Rnext=NULL;  
  97.             free(p0);  
  98.             p0=NULL;  
  99.         }  
  100.         else{  
  101.             temp=p0->Lnext;  
  102.             free(temp);  
  103.             p0->Lnext=NULL;  
  104.        }  
  105.     }  
  106. }  
  107.   
  108. void list::mid_print(){  
  109.   mid_tranverse(head);  
  110. }  
  111. void list::mid_tranverse(node* p){  
  112.    if(p==NULL)  
  113.        return;  
  114.    mid_tranverse(p->Lnext);  
  115.    cout<<p->num<<"    ";  
  116.    mid_tranverse(p->Rnext);  
  117. }  
  118.   
  119. //二叉排序树的初始化  
  120. list::list(){  
  121.     node* p;  
  122.     node* q;  
  123.     int i;  
  124.     cout<<"请输入您要输入的数字,按任意非数字键结束!"<<endl;  
  125.     cin>>i;  
  126.     if(cin.fail()){  
  127.         cout<<"您的输入有误"<<endl;  
  128.         exit(-1);  
  129.     }  
  130.     else{  
  131.           head=new node;  
  132.           head->num=i;  
  133.           head->Lnext=NULL;  
  134.           head->Rnext=NULL;  
  135.           while(1){  
  136.               cout<<"输入您要输入的数字:"<<endl;  
  137.               cin>>i;  
  138.               if(cin.fail())  
  139.                  break;  
  140.               p=new node;  
  141.               p->num=i;  
  142.               p->Lnext=NULL;  
  143.               p->Rnext=NULL;  
  144.               q=head;  
  145.               while(1){  
  146.                   if(p->num<q->num){  
  147.                       if(q->Lnext==NULL){  
  148.                           q->Lnext=p;  
  149.                           break;  
  150.                       }  
  151.                       else  
  152.                           q=q->Lnext;  
  153.                   }  
  154.                   else{  
  155.                       if(q->Rnext==NULL){  
  156.                           q->Rnext=p;  
  157.                           break;  
  158.                       }  
  159.                       else  
  160.                           q=q->Rnext;  
  161.                   }  
  162.              }  
  163.          }                     
  164.     }  
  165. }  
  166.   
  167. void main()  
  168. {  
  169.     list test;  
  170.     test.mid_print();  
  171.     cout<<endl<<endl;  
  172.     test.delete_place(4);  
  173.     test.mid_print();  
  174.     system("pause");  
  175. }  
  176.   
  177. /* 
  178. #include <iostream> 
  179.  using namespace std; 
  180.  typedef struct BSTNode 
  181.  { 
  182.      int key; 
  183.      struct BSTNode *lchild,*rchild; 
  184.  }BSTNode,*BSTree; 
  185.  //二叉排序树的插入——递归实现 
  186.  void InsertBST(BSTree &DT,BSTNode *p) 
  187.  { 
  188.      if(DT==NULL) 
  189.          DT=p; 
  190.      else if((DT->key) > (p->key)) 
  191.          InsertBST(DT->lchild,p); 
  192.      else 
  193.          InsertBST(DT->rchild,p); 
  194.  } 
  195.  //二叉排序树结点的删除 
  196.  void DeleteBST(BSTree &DT,BSTNode *p) 
  197.  {//要删除结点p,f是p的双亲 
  198.      BSTNode *f; 
  199.      BSTNode *q,*fq; 
  200.      if(!(p->lchild)&&!(p->rchild))//第一种情况:p是叶子结点 
  201.      { 
  202.          if(f->lchild==p)//p是左孩子 
  203.              f->lchild=NULL; 
  204.          else//p是右孩子 
  205.              f->rchild=NULL; 
  206.          q=p; 
  207.      } 
  208.      else if(!(p->rchild))//第二种情况:(1)p只有左子树 
  209.      { 
  210.          if(f->lchild==p) 
  211.              f->lchild=p->lchild; 
  212.          else 
  213.              f->rchild=p->lchild; 
  214.          q=p; 
  215.      } 
  216.      else if(!(p->lchild))//第二种情况:(2)p只有右子树 
  217.      { 
  218.          if(f->lchild==p) 
  219.              f->lchild=p->rchild; 
  220.          else 
  221.              f->rchild=p->rchild; 
  222.          q=p; 
  223.      } 
  224.      else //第三种情况:p既有左子树又有右子树 
  225.      {//用p的中序后继来代替p 
  226.          fq=p;//fq是q的双亲 
  227.          q=p->lchild; 
  228.          while(q->lchild) 
  229.          {//遍历找到p的中序后继 
  230.              fq=q; 
  231.              q=q->lchild; 
  232.          } 
  233.          p->key=q->key; 
  234.          if(fq==p) 
  235.              fq->rchild=q->rchild; 
  236.          else 
  237.              fq->lchild=q->rchild; 
  238.      } 
  239.      delete q; 
  240.  } 
  241.  //二叉排序树的构造 
  242.  void CreateBST(BSTree &DT,int n) 
  243.  { 
  244.      int i,j; 
  245.      int r[100]; 
  246.      BSTNode *s; 
  247.      DT=NULL;//这里一定要将DT置空,表示刚开始的时候是空树,不置空的话,编译器分配的DT是非空的 
  248.      for(j=0;j<n;j++) 
  249.          cin>>r[j]; 
  250.      for(i=0;i<n;i++) 
  251.      { 
  252.          s=new BSTNode; 
  253.          s->key=r[i]; 
  254.          s->lchild=NULL; 
  255.          s->rchild=NULL; 
  256.          InsertBST(DT,s); 
  257.      } 
  258.  } 
  259.  //二叉排序树的搜索——递归实现 
  260.  BSTNode * SearchBST(BSTree &DT,int k) 
  261.  { 
  262.      BSTNode *p; 
  263.      p=DT; 
  264.      if(DT==NULL) 
  265.          return NULL; 
  266.      else if(p->key==k) 
  267.          return p; 
  268.      else if(p->key>k) 
  269.          return SearchBST(p->lchild,k); 
  270.      else 
  271.          return SearchBST(p->rchild,k); 
  272.  } 
  273.  void main() 
  274.  { 
  275.      freopen("in.txt","r",stdin); 
  276.      BSTree DT; 
  277.      BSTNode *p; 
  278.      int k; 
  279.      CreateBST(DT,13); 
  280.      cin>>k; 
  281.      p=SearchBST(DT,k); 
  282.      cout<<p->key<<endl; 
  283.      //DeleteBST(DT,p); 
  284.  } 
  285. */  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值