数据结构之二叉排序树

//========================head.h=======================================
#define TRUE         1 
#define FALSE        0
#define OK           1 //成功
#define ERROR        0 //失败(错误)
#define INFEASIBLE  -1 //不可行的
#define MEMOVERFLOW -2 //(内存)溢出
#define UNDERFLOW   -4 //(数组下标)下溢
#define ENDELEM -9999 //序列结束元素(为方便演示而设)


#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))



typedef int Status; // 设关键字域为整型
 #define N 10 // 数据元素个数
 typedef int KeyType; // 设关键字域为整型
 struct ElemType // 数据元素类型
 {
   KeyType key;
   int others;
 };

     
typedef ElemType TElemType;

typedef struct BiTNode
{
   TElemType data;
   BiTNode *lchild,*rchild; // 左右孩子指针
}BiTNode,*BiTree;


//=======================================================================


#include
#include "head.h"
#include



 Status InitDSTable(BiTree &DT) // 同bo6-2.cpp
 { // 操作结果: 构造一个空的动态查找表DT
   DT=NULL;
   return OK;
 }

 void DestroyDSTable(BiTree &DT) // 同bo6-2.cpp
 { // 初始条件: 动态查找表DT存在。操作结果: 销毁动态查找表DT
   if(DT) // 非空树
   {
     if(DT->lchild) // 有左孩子
       DestroyDSTable(DT->lchild); // 销毁左孩子子树
     if(DT->rchild) // 有右孩子
       DestroyDSTable(DT->rchild); // 销毁右孩子子树
     free(DT); // 释放根结点
     DT=NULL; // 空指针赋0
   }
 }

 BiTree SearchBST(BiTree T,KeyType key)
 { // 在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,
   // 若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。算法9.5(a)
   if((!T)||EQ(key,T->data.key))
     return T; // 查找结束
   else if LT(key,T->data.key) // 在左子树中继续查找
     return SearchBST(T->lchild,key);
   else
     return SearchBST(T->rchild,key); // 在右子树中继续查找
 }

 void SearchBST(BiTree &T,KeyType key,BiTree f,BiTree &p,Status &flag) // 算法9.5(b)改
 { // 在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找
   // 成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上
   // 访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL
   if(!T) // 查找不成功
   {
     p=f;
     flag=FALSE;
   }
   else if EQ(key,T->data.key) //  查找成功
   {
     p=T;
     flag=TRUE;
   }
   else if LT(key,T->data.key)
     SearchBST(T->lchild,key,T,p,flag); // 在左子树中继续查找
   else
     SearchBST(T->rchild,key,T,p,flag); //  在右子树中继续查找
 }

 Status InsertBST(BiTree &T, ElemType e)
 { // 当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE,
   // 否则返回FALSE。算法9.6(改)
   BiTree p,s;
   Status flag;
   SearchBST(T,e.key,NULL,p,flag);
   if(!flag) // 查找不成功
   {
     s=(BiTree)malloc(sizeof(BiTNode));
     s->data=e;
     s->lchild=s->rchild=NULL;
     if(!p)
       T=s; // 被插结点*s为新的根结点
     else if LT(e.key,p->data.key)
       p->lchild=s; // 被插结点*s为左孩子
     else
       p->rchild=s; // 被插结点*s为右孩子
     return TRUE;
   }
   else
     return FALSE; // 树中已有关键字相同的结点,不再插入
 }

 void Delete(BiTree &p)
 { // 从二叉排序树中删除结点p,并重接它的左或右子树。算法9.8
   BiTree q,s;
   if(!p->rchild) // 右子树空则只需重接它的左子树(待删结点是叶子也走此分支)
   {
     q=p;
     p=p->lchild;
     free(q);
   }
   else if(!p->lchild) // 只需重接它的右子树
   {
     q=p;
     p=p->rchild;
     free(q);
   }
   else // 左右子树均不空
   {
     q=p;
     s=p->lchild;
     while(s->rchild) // 转左,然后向右到尽头(找待删结点的前驱)
     {
       q=s;
       s=s->rchild;
     }
     p->data=s->data; // s指向被删结点的"前驱"(将被删结点前驱的值取代被删结点的值)
     if(q!=p)
       q->rchild=s->lchild; // 重接*q的右子树
     else
       q->lchild=s->lchild; // 重接*q的左子树
     free(s);
   }
 }

 Status DeleteBST(BiTree &T,KeyType key)
 { // 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,
   // 并返回TRUE;否则返回FALSE。算法9.7
   if(!T) // 不存在关键字等于key的数据元素
     return FALSE;
   else
   {
     if EQ(key,T->data.key) // 找到关键字等于key的数据元素
       Delete(T);
     else if LT(key,T->data.key)
       DeleteBST(T->lchild,key);
     else
       DeleteBST(T->rchild,key);
     return TRUE;
   }
 }

//中序遍历
 void InTraverseDSTable(BiTree DT,void(*Visit)(ElemType))
 { // 初始条件: 动态查找表DT存在,Visit是对结点操作的应用函数
   // 操作结果: 按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次
   if(DT)
   {
     InTraverseDSTable(DT->lchild,Visit); // 先中序遍历左子树
     Visit(DT->data); // 再访问根结点
     InTraverseDSTable(DT->rchild,Visit); // 最后中序遍历右子树
   }
 }

 
 //前序遍历
 void PreTraverseDSTable(BiTree DT,void(*Visit)(ElemType))
 { // 初始条件: 动态查找表DT存在,Visit是对结点操作的应用函数
   // 操作结果: 按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次
   if(DT)
   {
     Visit(DT->data); // 再访问根结点
PreTraverseDSTable(DT->lchild,Visit); // 先前序遍历左子树
     PreTraverseDSTable(DT->rchild,Visit); // 最后前序遍历右子树
   }
 }


//后序遍历
 void PostTraverseDSTable(BiTree DT,void(*Visit)(ElemType))
 { // 初始条件: 动态查找表DT存在,Visit是对结点操作的应用函数
   // 操作结果: 按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次
   if(DT)
   {
     Visit(DT->data); // 再访问根结点
PostTraverseDSTable(DT->lchild,Visit); // 先后序遍历左子树
     PostTraverseDSTable(DT->rchild,Visit); // 最后后序遍历右子树
   }
 }

 void print(ElemType c)
 {
   printf("(%d,%d) ",c.key,c.others);
 }

 void main()
 {
   BiTree dt,p;
   int i;
   KeyType j;
   ElemType r[N]={{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},{100,7},{61,8},{90,9},{78,10}}; // 以教科书图9.7(a)为例
   InitDSTable(dt); // 构造空表
   for(i=0;i < N;i++)
     InsertBST(dt,r[i]); // 依次插入数据元素
   printf("先序遍历\n");
   PreTraverseDSTable(dt,print);
   printf("\n中序遍历\n");
   InTraverseDSTable(dt,print);
   printf("\n后序遍历\n");
   PostTraverseDSTable(dt,print);
   printf("\n请输入待查找的值: ");
   scanf("%d",&j);
   p=SearchBST(dt,j);
   if(p)
   {
printf("表中存在此值。");
DeleteBST(dt,j);
printf("删除此值后:\n");
printf("\n先序遍历\n");
PreTraverseDSTable(dt,print);
printf("\n中序遍历\n");
InTraverseDSTable(dt,print);
printf("\n后序遍历\n");
PostTraverseDSTable(dt,print);
printf("\n");
   }
   else
printf("表中不存在此值\n");
   DestroyDSTable(dt);
 }
 
 
 
 


转载于:https://www.cnblogs.com/dreamsyeah/p/5878411.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值