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

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

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

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

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

下面是代码:

文件"tree.h"

[cpp]

#include<iostream>    #include<stack>    #include<queue>    using namespace std;      #define MAX_NODE_NUM 20 //树结点最大值    class Bin_Sort_Tree;   //树结点    class BSTnode   {       int tag;//后序遍历作为访问标志        int data;       BSTnode *lchild;       BSTnode *rchild;       friend class Bin_Sort_Tree;   };      //二叉排序树    class Bin_Sort_Tree   {   public:        int Get_data(BSTnode *p)       {           return p->data;       }          bool Search_BST(BSTnode *T,int a,BSTnode *&f,BSTnode *&p)       {           /*-----------------------------          /在树中查找值为a的结点,查找到           /了,用p保存该结点地址,f指向           /p的双亲结点                             /-----------------------------*/           p=T;           while(p)           {               if(p->data==a)                   return true;               else if(p->data>a)               {                   f=p;                   p=p->lchild;               }               else               {                   f=p;                   p=p->rchild;               }           }           return false;       }              //将值为a的结点插入树中,若值已存在,就不插入        void Insert_BST_1(BSTnode *&T,int a)       {           BSTnode *f=NULL;           BSTnode *p=NULL;           if(Search_BST(T,a,f,p))               return//树中已有值相同结点,不插入            else           {               BSTnode *s=new BSTnode;               s->data=a;               s->lchild=s->rchild=NULL;               if(s->data>f->data)                   f->rchild=s;               else                   f->lchild=s;           }       }              void Insert_BST_2(BSTnode *&T,int a) //插入算法递归实现        {              if(!T)           {               cout<<"树为空"<<endl;               return;           }           if(T->data>a)           {               if(!T->lchild)               {                   T->lchild=new BSTnode;                   T->lchild->data=a;                   T->lchild->lchild=NULL;                   T->lchild->rchild=NULL;                   return;               }               else                   Insert_BST_2(T->lchild,a);           }           if(T->data<a)           {               if(!T->rchild)               {                   T->rchild=new BSTnode;                   T->rchild->data=a;                   T->rchild->lchild=NULL;                   T->rchild->rchild=NULL;                   return;               }               else                   Insert_BST_2(T->rchild,a);           }          }          void Create_BSTree(BSTnode *&T) //建树        {           cout<<"输入二叉排序树的元素,输入-1代表结束输入:";           int num[MAX_NODE_NUM];           int a,i=0;           while(cin>>a && a!=-1)           {               num[i]=a;               i++;           }                      if(num[0]==-1)           {               cout<<"排序树为空"<<endl;               return;           }              int k=i;           T=new BSTnode;           T->data=num[0];           T->lchild=T->rchild=NULL;           for(i=1;i<k;i++)               Insert_BST_1(T,num[i]);           cout<<"____建树完成____"<<endl;       }          void Delete_BST(BSTnode *&T,int a)//删除结点值为a的结点        {           /*---------------------------------------------------------          / 从树中删除一个节点后,要保证删后的树还是一棵二叉排序树,           / 删除前,首先是在树中查找是否有这个结点,用p指向该结点,            / 用f指向p的双亲结点,这个结点在树中的位置有下面四种情况:            /                                                                    / 1:如果p指向的结点是叶子结点,那么直接将f指针的左子树或者           / 右子树置空,然后删除p结点即可。                                    /                                                                    / 2:如果p指向的结点是只有左子树或右子树,那么只需要让p结点           / 原来在f中的位置(左子树或右子树)用p的子树代替即可。                 /                                                                    / 3:如果p所指向的结点是根节点,那么直接将根节点置空                  /                                                                    / 4:如果p所指向的结点左右子树都非空,为了删除p后原序列的顺           / 序不变,就需要在原序列中先找出p的直接前驱(或者直接后继)            / 结点用那个结点的值来代替p结点的值,然后再删掉那个直接前            / 驱(或者直接后继)结点。                                             / 在中序遍历序列中找结点的直接前驱的方法是顺着结点的左孩子           / 的右链域开始,一直到结点右孩子为空为止。                           /---------------------------------------------------------*/              BSTnode *f=NULL;           BSTnode *p=NULL;           BSTnode *q=NULL;           BSTnode *s=NULL;           if(Search_BST(T,a,f,p))           {               if(p->lchild && p->rchild)               {                   q=p;                   s=p->lchild;                   while(s->rchild)                   {                       q=s;                       s=s->rchild;                   }                   p->data=s->data;                   //s指向要删除结点的直接前驱,且s是一定没有右子树的                    if(q!=p)                       q->rchild=s->lchild;                   else                       q->lchild=s->lchild;//这种情况是,q的左子树的右子树为空时                    delete s;                   cout<<"结点删除成功"<<endl;                   return ;               }               else                {                   if(!p->lchild) //左子树为空                    {                       q=p;                       p=p->rchild;                   }                   else        //右子树为空                    {                       q=p;                       p=p->lchild;                   }                   //下面将p所指向的子树连接到f所指(被删结点的双亲)的结点上                    if(!T) //被删的结点为根节点                        T=p;                   else if(q==f->lchild)                       f->lchild=p;                   else                       f->rchild=p;                   delete q;                   cout<<"结点删除成功"<<endl;                   return;               }           }           else           {               cout<<"要删除的结点不存在"<<endl;               return ;           }       }          //下面是二叉树的四种遍历方式,都是非递归方式实现               void PreOrder_Traverse(BSTnode *T) //前序遍历        {           stack<BSTnode *> s;           BSTnode *p;           p=T;           while(p || !s.empty())           {               if(p)               {                   cout<<p->data<<"  ";                   s.push(p);                   p=p->lchild;               }               else               {                   p=s.top();                   s.pop();                   p=p->rchild;               }           }       }          void InOrder_Traverse(BSTnode *T) //中序遍历        {           stack<BSTnode *> s;           BSTnode *p=T;           while(p || !s.empty())           {               if(p)               {                   s.push(p);                   p=p->lchild;               }               else               {                   p=s.top();                   s.pop();                   cout<<p->data<<"  ";                   p=p->rchild;               }           }       }          void PostOrder_Traverse(BSTnode *T) //后序遍历        {           stack<BSTnode *> s;           BSTnode *p=T;           while(p || !s.empty())           {               if(p)               {                   p->tag=0;                   s.push(p);                   p=p->lchild;               }               else               {                   p=s.top();                   if(p->tag)                   {                       cout<<p->data<<"  ";                       s.pop();                       p=NULL;                   }                   else                   {                       p->tag=1;                       p=p->rchild;                   }               }           }       }          void LevelOrder_Traverse(BSTnode *T) //层次遍历        {           queue<BSTnode *> q;           BSTnode *p=T;           q.push(p);           while(!q.empty())           {               p=q.front();               q.pop();               cout<<p->data<<"  ";               if(p->lchild)                   q.push(p->lchild);               if(p->rchild)                   q.push(p->rchild);           }       }   };  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wydwgd.html