• 二叉排序树


    二叉排序树,又称为二叉查找树。它或者是一颗空树,或者具有下列性质的二叉树。

    • 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;

    • 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;

    • 它的左、右子树也分别为二叉排序树。

     

    二叉排序树的难点在于删除操作

    删除节点有三种情况分析:

            a. 叶子节点;(直接删除即可)



     

     b. 仅有左或右子树的节点;(上移子树即可)

     

     c. 左右子树都有的节点。( 用删除节点的直接前驱或者直接后继来替换当前节点,调整直接前驱或者直接后继的位置)

     

     二叉排序树的基本操作:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef struct tree{//二叉树节点结构定义 
      5     int date;
      6     struct tree *lchild,*rchild;//定义左右子树 
      7 }Binode,*Bitree;
      8 
      9 void insert(Bitree t,int date){//插入 
     10     Bitree p,s,fa;
     11     p=t;
     12     while(p){//查找date应在的位置 
     13         if(date<p->date){
     14             fa=p;
     15             p=p->lchild;
     16         }
     17         else if(date>p->date){
     18             fa=p;
     19             p=p->rchild;
     20         }else{
     21             cout<<"已存在"<<endl;
     22             return ;
     23         }
     24     }//由于buildit为&t,此处fa和p的操作都直接作用于t上。 
     25     s=(Bitree)malloc(sizeof(Binode));//申请空间 
     26     s->date=date;
     27     s->lchild=s->rchild=NULL; 
     28     if(s->date<fa->date){
     29         fa->lchild=s;
     30         cout<<"已插入"<<s->date<<endl; 
     31     }
     32     else{
     33         fa->rchild=s;
     34         cout<<"已插入"<<s->date<<endl;
     35     }
     36 }
     37 
     38 void Buildit(Bitree &t,int n){//构建二叉排序树 
     39     int date;
     40     cin>>date;
     41     t=(Bitree)malloc(sizeof(Binode));//申请空间 
     42     t->date=date;
     43     t->lchild=t->rchild=NULL;//将左右子树设为NULL 
     44     for(int i=1;i<n;i++){//插如n次 
     45         cin>>date;
     46         insert(t,date);
     47         cout<<"创建完毕"<<endl;
     48     }
     49     
     50 }
     51 
     52 int search1(Bitree t,int key){//搜索节点(非递归) 
     53     Bitree p;
     54     p=t;
     55     while(p){
     56         if(key< p->date){
     57             p=p->lchild;
     58         }else if(key> p->date){
     59             p=p->rchild;
     60         }
     61         else{
     62             cout<<"已找到"<<p->date<<endl;
     63             return 1;
     64         }
     65     }
     66     return 0;
     67 } 
     68 
     69 int search2(Bitree t,int key){//搜索节点(递归) 
     70     Bitree p;
     71     p=t;
     72     if(!t){
     73         return 0;
     74     }
     75     if(p->date==key){
     76         cout<<"已找到"<<p->date<<endl;
     77         return 1;
     78     }else if(p->date<key){
     79         return search2(p->rchild,key);
     80     }else{
     81         return search2(p->lchild,key);
     82     }
     83 }
     84 
     85 void Delete(Bitree t,int key){//删除节点 
     86     Bitree p,cur,par;
     87     p=t;
     88     while(p){//查找节点位置 
     89         if(key==p->date){
     90             break;
     91         }else if(key<p->date){
     92             par=p;
     93             p=p->lchild;
     94         }else{
     95             par=p;
     96             p=p->rchild;
     97         }
     98     }
     99     if(!p){
    100         return ;
    101     }
    102     if(!p->lchild){//没有左子树 
    103         if(p==t){//根节点 
    104             t=p->rchild;
    105         }else if(par->lchild==p){//par为p的父节点 
    106             par->lchild=p->rchild; 
    107         }else{
    108             par->rchild=p->rchild;
    109         }
    110     }else{//有左子树 
    111         cur=p->lchild;
    112         par=cur;
    113         while(cur->rchild){
    114             par=cur;
    115             cur=cur->rchild;
    116         }
    117         if(par==p->lchild){//p的左孩子没有右子树 
    118             p->date=par->date;
    119             p->lchild=par->lchild;
    120             free(par);
    121         }
    122         else{//有右子树 
    123             p->date=cur->date;
    124             par->rchild=cur->lchild;
    125             free(cur); 
    126         }
    127     } 
    128 }
    129 
    130 void Inorder(Bitree t){
    131     if(!t)
    132     return ;
    133     Inorder(t->lchild);
    134     cout<<t->date<<" ";
    135     Inorder(t->rchild); 
    136 }
    137 
    138 int main(){
    139     Bitree t;
    140     int n,key,select;
    141     while(1){
    142         printf("        ------------------
    ");  
    143         printf("        1、建立二叉排序树
    ");  
    144         printf("        2、输出中序遍历结果
    ");  
    145         printf("        3、搜索数据
    ");  
    146         printf("        4、删除数据
    ");  
    147         printf("        5、插入数据
    ");  
    148         printf("        6、搜索数据(递归)
    ");   
    149         printf("        ------------------
    ");
    150         cin>>select;
    151         switch(select){
    152             case 1:
    153                 cin>>n;
    154                 Buildit(t,n);
    155                 break;
    156             case 2:
    157                 Inorder(t);
    158                 cout<<endl;
    159                 break;
    160             case 3:
    161                 cin>>key;
    162                 search1(t,key);
    163                 break;
    164             case 4:
    165                 cin>>key;
    166                 Delete(t,key);
    167                 break;
    168             case 5:
    169                 cin>>key;
    170                 insert(t,key);
    171                 break;
    172             case 6:
    173                 cin>>key;
    174                 search2(t,key);
    175                 break; 
    176             default:
    177             return 0;    
    178         } 
    179     }
    180     return 0;
    181 }

     

  • 相关阅读:
    mahout下的KMeans Clustering实现
    信号量、互斥体和自旋锁
    找出二叉树中两个节点的最低共同父节点
    C/C++中volatile关键字
    函数指针和指针函数
    java终止线程的通用机制
    我的一次重构实践
    新手浅谈Future
    线程中添加线程
    死锁
  • 原文地址:https://www.cnblogs.com/Kiven5197/p/8877177.html
Copyright © 2020-2023  润新知