二叉排序树(二叉搜索树)

动态查找表的一种理想数据结构。

二叉排序树的定义是:二叉排序树T是一棵树,它或者是空,或者具备一下三条性质:

(1)、如果T的根节点的左子树非空,其左子树所有结点的值均小于T的根节点的值

(2)、如果T的根节点的右子树非空,其右子树所有结点的值均大于T的根节点的值
(3)、T的根结点的左右子树均为二叉排序树

下面是代码:

文件"tree.h"

  1. #include<iostream>  
  2. #include<stack>  
  3. #include<queue>  
  4. using namespace std;  
  5.   
  6. #define MAX_NODE_NUM 20 //树结点最大值  
  7. class Bin_Sort_Tree;  
  8. //树结点  
  9. class BSTnode  
  10. {  
  11.     int tag;//后序遍历作为访问标志  
  12.     int data;  
  13.     BSTnode *lchild;  
  14.     BSTnode *rchild;  
  15.     friend class Bin_Sort_Tree;  
  16. };  
  17.   
  18. //二叉排序树  
  19. class Bin_Sort_Tree  
  20. {  
  21. public:   
  22.     int Get_data(BSTnode *p)  
  23.     {  
  24.         return p->data;  
  25.     }  
  26.   
  27.     bool Search_BST(BSTnode *T,int a,BSTnode *&f,BSTnode *&p)  
  28.     {  
  29.         /*----------------------------- 
  30.         /在树中查找值为a的结点,查找到  
  31.         /了,用p保存该结点地址,f指向  
  32.         /p的双亲结点                    
  33.         /-----------------------------*/  
  34.         p=T;  
  35.         while(p)  
  36.         {  
  37.             if(p->data==a)  
  38.                 return true;  
  39.             else if(p->data>a)  
  40.             {  
  41.                 f=p;  
  42.                 p=p->lchild;  
  43.             }  
  44.             else  
  45.             {  
  46.                 f=p;  
  47.                 p=p->rchild;  
  48.             }  
  49.         }  
  50.         return false;  
  51.     }  
  52.       
  53.     //将值为a的结点插入树中,若值已存在,就不插入  
  54.     void Insert_BST_1(BSTnode *&T,int a)  
  55.     {  
  56.         BSTnode *f=NULL;  
  57.         BSTnode *p=NULL;  
  58.         if(Search_BST(T,a,f,p))  
  59.             return//树中已有值相同结点,不插入  
  60.         else  
  61.         {  
  62.             BSTnode *s=new BSTnode;  
  63.             s->data=a;  
  64.             s->lchild=s->rchild=NULL;  
  65.             if(s->data>f->data)  
  66.                 f->rchild=s;  
  67.             else  
  68.                 f->lchild=s;  
  69.         }  
  70.     }  
  71.       
  72.     void Insert_BST_2(BSTnode *&T,int a) //插入算法递归实现  
  73.     {     
  74.         if(!T)  
  75.         {  
  76.             cout<<"树为空"<<endl;  
  77.             return;  
  78.         }  
  79.         if(T->data>a)  
  80.         {  
  81.             if(!T->lchild)  
  82.             {  
  83.                 T->lchild=new BSTnode;  
  84.                 T->lchild->data=a;  
  85.                 T->lchild->lchild=NULL;  
  86.                 T->lchild->rchild=NULL;  
  87.                 return;  
  88.             }  
  89.             else  
  90.                 Insert_BST_2(T->lchild,a);  
  91.         }  
  92.         if(T->data<a)  
  93.         {  
  94.             if(!T->rchild)  
  95.             {  
  96.                 T->rchild=new BSTnode;  
  97.                 T->rchild->data=a;  
  98.                 T->rchild->lchild=NULL;  
  99.                 T->rchild->rchild=NULL;  
  100.                 return;  
  101.             }  
  102.             else  
  103.                 Insert_BST_2(T->rchild,a);  
  104.         }  
  105.   
  106.     }  
  107.   
  108.     void Create_BSTree(BSTnode *&T) //建树  
  109.     {  
  110.         cout<<"输入二叉排序树的元素,输入-1代表结束输入:";  
  111.         int num[MAX_NODE_NUM];  
  112.         int a,i=0;  
  113.         while(cin>>a && a!=-1)  
  114.         {  
  115.             num[i]=a;  
  116.             i++;  
  117.         }  
  118.           
  119.         if(num[0]==-1)  
  120.         {  
  121.             cout<<"排序树为空"<<endl;  
  122.             return;  
  123.         }  
  124.   
  125.         int k=i;  
  126.         T=new BSTnode;  
  127.         T->data=num[0];  
  128.         T->lchild=T->rchild=NULL;  
  129.         for(i=1;i<k;i++)  
  130.             Insert_BST_1(T,num[i]);  
  131.         cout<<"____建树完成____"<<endl;  
  132.     }  
  133.   
  134.     void Delete_BST(BSTnode *&T,int a)//删除结点值为a的结点  
  135.     {  
  136.         /*--------------------------------------------------------- 
  137.         / 从树中删除一个节点后,要保证删后的树还是一棵二叉排序树,  
  138.         / 删除前,首先是在树中查找是否有这个结点,用p指向该结点,   
  139.         / 用f指向p的双亲结点,这个结点在树中的位置有下面四种情况:   
  140.         /                                                           
  141.         / 1:如果p指向的结点是叶子结点,那么直接将f指针的左子树或者  
  142.         / 右子树置空,然后删除p结点即可。                           
  143.         /                                                           
  144.         / 2:如果p指向的结点是只有左子树或右子树,那么只需要让p结点  
  145.         / 原来在f中的位置(左子树或右子树)用p的子树代替即可。        
  146.         /                                                           
  147.         / 3:如果p所指向的结点是根节点,那么直接将根节点置空         
  148.         /                                                           
  149.         / 4:如果p所指向的结点左右子树都非空,为了删除p后原序列的顺  
  150.         / 序不变,就需要在原序列中先找出p的直接前驱(或者直接后继)   
  151.         / 结点用那个结点的值来代替p结点的值,然后再删掉那个直接前   
  152.         / 驱(或者直接后继)结点。                                    
  153.         / 在中序遍历序列中找结点的直接前驱的方法是顺着结点的左孩子  
  154.         / 的右链域开始,一直到结点右孩子为空为止。                  
  155.         /---------------------------------------------------------*/  
  156.   
  157.         BSTnode *f=NULL;  
  158.         BSTnode *p=NULL;  
  159.         BSTnode *q=NULL;  
  160.         BSTnode *s=NULL;  
  161.         if(Search_BST(T,a,f,p))  
  162.         {  
  163.             if(p->lchild && p->rchild)  
  164.             {  
  165.                 q=p;  
  166.                 s=p->lchild;  
  167.                 while(s->rchild)  
  168.                 {  
  169.                     q=s;  
  170.                     s=s->rchild;  
  171.                 }  
  172.                 p->data=s->data;  
  173.                 //s指向要删除结点的直接前驱,且s是一定没有右子树的  
  174.                 if(q!=p)  
  175.                     q->rchild=s->lchild;  
  176.                 else  
  177.                     q->lchild=s->lchild;//这种情况是,q的左子树的右子树为空时  
  178.                 delete s;  
  179.                 cout<<"结点删除成功"<<endl;  
  180.                 return ;  
  181.             }  
  182.             else   
  183.             {  
  184.                 if(!p->lchild) //左子树为空  
  185.                 {  
  186.                     q=p;  
  187.                     p=p->rchild;  
  188.                 }  
  189.                 else        //右子树为空  
  190.                 {  
  191.                     q=p;  
  192.                     p=p->lchild;  
  193.                 }  
  194.                 //下面将p所指向的子树连接到f所指(被删结点的双亲)的结点上  
  195.                 if(!T) //被删的结点为根节点  
  196.                     T=p;  
  197.                 else if(q==f->lchild)  
  198.                     f->lchild=p;  
  199.                 else  
  200.                     f->rchild=p;  
  201.                 delete q;  
  202.                 cout<<"结点删除成功"<<endl;  
  203.                 return;  
  204.             }  
  205.         }  
  206.         else  
  207.         {  
  208.             cout<<"要删除的结点不存在"<<endl;  
  209.             return ;  
  210.         }  
  211.     }  
  212.   
  213.     //下面是二叉树的四种遍历方式,都是非递归方式实现  
  214.       
  215.     void PreOrder_Traverse(BSTnode *T) //前序遍历  
  216.     {  
  217.         stack<BSTnode *> s;  
  218.         BSTnode *p;  
  219.         p=T;  
  220.         while(p || !s.empty())  
  221.         {  
  222.             if(p)  
  223.             {  
  224.                 cout<<p->data<<"  ";  
  225.                 s.push(p);  
  226.                 p=p->lchild;  
  227.             }  
  228.             else  
  229.             {  
  230.                 p=s.top();  
  231.                 s.pop();  
  232.                 p=p->rchild;  
  233.             }  
  234.         }  
  235.     }  
  236.   
  237.     void InOrder_Traverse(BSTnode *T) //中序遍历  
  238.     {  
  239.         stack<BSTnode *> s;  
  240.         BSTnode *p=T;  
  241.         while(p || !s.empty())  
  242.         {  
  243.             if(p)  
  244.             {  
  245.                 s.push(p);  
  246.                 p=p->lchild;  
  247.             }  
  248.             else  
  249.             {  
  250.                 p=s.top();  
  251.                 s.pop();  
  252.                 cout<<p->data<<"  ";  
  253.                 p=p->rchild;  
  254.             }  
  255.         }  
  256.     }  
  257.   
  258.     void PostOrder_Traverse(BSTnode *T) //后序遍历  
  259.     {  
  260.         stack<BSTnode *> s;  
  261.         BSTnode *p=T;  
  262.         while(p || !s.empty())  
  263.         {  
  264.             if(p)  
  265.             {  
  266.                 p->tag=0;  
  267.                 s.push(p);  
  268.                 p=p->lchild;  
  269.             }  
  270.             else  
  271.             {  
  272.                 p=s.top();  
  273.                 if(p->tag)  
  274.                 {  
  275.                     cout<<p->data<<"  ";  
  276.                     s.pop();  
  277.                     p=NULL;  
  278.                 }  
  279.                 else  
  280.                 {  
  281.                     p->tag=1;  
  282.                     p=p->rchild;  
  283.                 }  
  284.             }  
  285.         }  
  286.     }  
  287.   
  288.     void LevelOrder_Traverse(BSTnode *T) //层次遍历  
  289.     {  
  290.         queue<BSTnode *> q;  
  291.         BSTnode *p=T;  
  292.         q.push(p);  
  293.         while(!q.empty())  
  294.         {  
  295.             p=q.front();  
  296.             q.pop();  
  297.             cout<<p->data<<"  ";  
  298.             if(p->lchild)  
  299.                 q.push(p->lchild);  
  300.             if(p->rchild)  
  301.                 q.push(p->rchild);  
  302.         }  
  303.     }  
  304. };  

主函数"main.cpp"

  1. #include"tree.h"  
  2.   
  3. int main()  
  4. {  
  5.     Bin_Sort_Tree tree;  
  6.     BSTnode *root=NULL;  
  7.       
  8.     cout<<"_____建立二叉排序树____"<<endl;  
  9.     tree.Create_BSTree(root);  
  10.   
  11.     cout<<"前序遍历二叉树为:";  
  12.     tree.PreOrder_Traverse(root);  
  13.     cout<<endl;  
  14.   
  15.     cout<<"中序遍历二叉树为:";  
  16.     tree.InOrder_Traverse(root);  
  17.     cout<<endl;  
  18.   
  19.     cout<<"后序遍历二叉树为:";  
  20.     tree.PostOrder_Traverse(root);  
  21.     cout<<endl;  
  22.   
  23.     cout<<"层次遍历二叉树为:";  
  24.     tree.LevelOrder_Traverse(root);  
  25.     cout<<endl;  
  26.   
  27.     int data;  
  28.     BSTnode *f=NULL;  
  29.     BSTnode *p=NULL;  
  30.     cout<<"输入你要搜索的结点的值:";  
  31.     cin>>data;  
  32.     if(tree.Search_BST(root,data,f,p))  
  33.     {  
  34.         cout<<"你所搜索的结点地址为:"<<p<<endl;  
  35.         cout<<"他的双亲结点值为:"<<tree.Get_data(f)<<endl;  
  36.     }  
  37.     else  
  38.         cout<<"树中没有你要找的结点"<<endl;  
  39.   
  40.     cout<<"输入你要删除的结点的值:";  
  41.     cin>>data;  
  42.     tree.Delete_BST(root,data);  
  43.     cout<<"删除后的二叉树的中序遍历为:";  
  44.     tree.InOrder_Traverse(root);  
  45.     cout<<endl;  
  46.   
  47.     cout<<"输入你要插入树中的值:";  
  48.     cin>>data;  
  49.     tree.Insert_BST_2(root,data);  
  50.     cout<<"插入后,树的中序遍历为:";  
  51.     tree.InOrder_Traverse(root);  
  52.     cout<<endl;  
  53.   
  54.     return 0;  
  55. }  

下面是测试结果

  1. _____建立二叉排序树____  
  2. 输入二叉排序树的元素,输入-1代表结束输入:5 7 3 2 9 4 8 8 1 10 -1  
  3. ____建树完成____  
  4. 前序遍历二叉树为:5  3  2  1  4  7  9  8  10  
  5. 中序遍历二叉树为:1  2  3  4  5  7  8  9  10  
  6. 后序遍历二叉树为:1  2  4  3  8  10  9  7  5  
  7. 层次遍历二叉树为:5  3  7  2  4  9  1  8  10  
  8. 输入你要搜索的结点的值:7  
  9. 你所搜索的结点地址为:00380D18  
  10. 他的双亲结点值为:5  
  11. 输入你要删除的结点的值:10  
  12. 结点删除成功  
  13. 删除后的二叉树的中序遍历为:1  2  3  4  5  7  8  9  
  14. 输入你要插入树中的值:6  
  15. 插入后,树的中序遍历为:1  2  3  4  5  6  7  8  9  
  16. Press any key to continue  

按照一开始建树时的输入,生成的树为:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值