二叉树二叉链表实现基本操作

花了一天时间写了个二叉树用二叉链表实现基本操作,主要是对链表不熟悉,所以花了很多时间。

其次是对之前的线性表不熟,所以想了一些更麻烦的方法来实现。慢慢来吧。

今天至少还是想明白了二叉链表的大概结构和基本操作方法的。

附上代码,以后如果强化了再来贴。

 

 

/**************************用二叉链表法实现二叉树*********************************************/
/***************************存储表示***********************/
typedef struct BiTNode{
 char data;
 struct BiTNode *Lchild,*Rchild;
}BiTNode,*BiTree;

struct BiTreeQueue{
 BiTree t;
 struct BiTreeQueue *next;
};

/*********************基本操作*****************************/

//1结构初始化
void InitBiTree(BiTree &T){
//操作结果:构造空二叉树T。
 T= new BiTNode;
    if(!T) exit(1);
 T=NULL;
}

void CreateBiTree(BiTree &T){
//操作结果:按构造二叉树T。
 char ch;
 scanf("%c",&ch);
 getchar();
 if(ch!='/n'){
  T=(BiTree)malloc(sizeof(BiTNode));//创建新子树
  T->data=ch;
        printf("请输入%c的左子树,若无请按两下回车/n",ch);
  CreateBiTree(T->Lchild);//创建左子树
  printf("请输入%c的右子树,若无请按两下#/n",ch);
  CreateBiTree(T->Rchild);//创建右子树
 }
 else
  T=NULL;
}

//2销毁结构
void DestroyBiTree(BiTree &T){
//初始条件:二叉树T存在。
//操作结果:销毁二叉树T。
 if(T){//T存在
  if(T->Lchild)//T有左子树
   DestroyBiTree(T->Lchild);//销毁左子树
  if(T->Rchild)//T有右子树
   DestroyBiTree(T->Rchild);//销毁右子树
  free(T);//释放根节点T
  T=NULL;//空指针赋值为NULL
 }
}

bool BiTreeEmpty(BiTree T){
//初始条件:二叉树T存在。
//操作结果:若T为空二叉树,则返回TRUE,否则返回FALSE。
 if(T){//T存在
  if(T->data!=NULL)//T不为空
   return false;
 }
 return true;
}

int BiTreeDepth(BiTree T){
//初始条件:二叉树T存在。
//操作结果:返回T的深度。
 if(T){//T存在
  if(BiTreeDepth(T->Lchild)>=BiTreeDepth(T->Rchild))//左子树的深度大于等于右子树的深度
   return BiTreeDepth(T->Lchild)+1;
  else
   return BiTreeDepth(T->Rchild)+1;
 }
 return 0;//T不存在,返回0;
}

char Root(BiTree T){
//初始条件:二叉树T存在。
//操作结果:返回T的根。
 if(T)//T存在
  return T->data;
 return NULL;
}

char Value(BiTree T,BiTNode e){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:返回e的值。
 return e.data;
}

BiTree Point(BiTree T,char e){
//初始条件:T存在,e是T中某个结点
//操作结果:返回指向e的指针
 struct BiTreeQueue *bt,*bw,*a,*c;//构建一个BiTree类型的链表结构
    if(T){//非空树
  bt=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
  bt->t=T;
  bt->next=NULL;
  bw=bt;//根结点入链表
  while(bt){//链表不为空
          a=bt;//链表的头结点出列
    if(a->t->data==e)
     return a->t;//找到指向e的指针
    if(a->t->Lchild){//左子树存在
     c=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
     c->t=a->t->Lchild;
     c->next=NULL;
     bw->next=c;
     bw=bw->next;//左子树入链表;
    }
    if(a->t->Rchild){//右子树存在
     c=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
     c->t=a->t->Rchild;
     c->next=NULL;
     bw->next=c;
     bw=bw->next;//右子树入链表;
    }
    bt=bt->next;
    free(a);
  }
 }
 return NULL;//找不到
}

 

char Parent(BiTree T,char e){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:若e是T的非根结点,则返回它的双亲,否则返回“空”。
  struct BiTreeQueue *bt,*bw,*a,*c;//构建一个BiTree类型的链表结构
    if(T){//非空树
  bt=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
  bt->t=T;
  bt->next=NULL;
  bw=bt;//根结点入链表
  while(bt){//链表不为空
          a=bt;//链表的头结点出列
    if(a->t->Lchild){//左子树存在
     if(a->t->Lchild->data==e)
      return a->t->data;//找到指向e的指针
     c=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
     c->t=a->t->Lchild;
     c->next=NULL;
     bw->next=c;
     bw=bw->next;//左子树入链表;
    }
    if(a->t->Rchild){//右子树存在
     if(a->t->Rchild->data==e)
      return a->t->data;//找到指向e的指针
     c=(struct BiTreeQueue *)malloc(sizeof(struct BiTreeQueue));
     c->t=a->t->Rchild;
     c->next=NULL;
     bw->next=c;
     bw=bw->next;//右子树入链表;
    }
    bt=bt->next;
    free(a);
  }
 }
 return NULL;//找不到
}
char LeftChild(BiTree T,char e){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:返回e的左孩子。若e无左孩子,则返回“空”。
 BiTree a;
 if(T){
  a=Point(T,e);
  if(a){
   if(a->Lchild)
    return a->Lchild->data;
  }
 }
 return NULL;
}

char RightChild(BiTree T,char e){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:返回e的右孩子。若e无右孩子,则返回“空”。
 BiTree a;
 if(T){
  a=Point(T,e);
  if(a){
   if(a->Rchild)
    return a->Rchild->data;
  }
 }
 return NULL;
}

char LeftSibling(BiTree T,char e){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:返回e的左兄弟。若e是其双亲的左孩子或无左兄弟,则返回“空”。
 char ch;
 BiTree a;
 ch=Parent(T,e);
 a=Point(T,ch);
 if(a){
  if(!a->Lchild || a->Lchild->data==e)
   return NULL;
  else
   return a->Lchild->data;
 }
}
char RightSibling(BiTree T,char e){
//初始条件:二叉树T存在,e是T的结点。
//操作结果:返回e的右兄弟。若e是其双亲的右孩子或无右兄弟,则返回“空”。
 char ch;
 BiTree a;
 ch=Parent(T,e);
 a=Point(T,ch);
 if(a){
  if(!a->Rchild || a->Rchild->data==e)
   return NULL;
  else
   return a->Rchild->data;
 }
}
 void PreOrderTraverse(BiTree T)
 { // 初始条件: 二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动
   // 操作结果: 先序递归遍历T,对每个结点调用函数Visit一次且仅一次
   if(T) // T不空
   {
     // 先访问根结点
  printf("%c",T->data);
     PreOrderTraverse(T->Lchild); // 再先序遍历左子树
     PreOrderTraverse(T->Rchild); // 最后先序遍历右子树
   }
 }

 void InOrderTraverse(BiTree T)
 { // 初始条件: 二叉树T存在,Visit是对结点操作的应用函数
   // 操作结果: 中序递归遍历T,对每个结点调用函数Visit一次且仅一次
   if(T)
   {
     InOrderTraverse(T->Lchild); // 先中序遍历左子树
     // 再访问根结点
  printf("%c",T->data);
     InOrderTraverse(T->Rchild); // 最后中序遍历右子树
   }
 }
//void PostOrderTraverse(BiTree T,visit());
//初始条件:二叉树T存在,visit是对结点操作的应用函数。
//操作结果:后序遍历T,对每个结点调用函数visit一次且仅一次。一旦visit()失
//败,则操作失败。
//void LevelOrderTraverse(BiTree T,visit());
//初始条件:二叉树T存在,visit是对结点操作的应用函数。
//操作结果:层序遍历T,对每个结点调用函数visit一次且仅一次.一旦visit()失
//败,则操作失败。

void ClearBiTree(BiTree &T){
//初始条件:二叉树T存在。
//操作结果:将二叉树T清为空树
 if(T){
  T->data=NULL;
  ClearBiTree(T->Lchild);
  ClearBiTree(T->Rchild);
  free(T);
  T=NULL;
 }
}

void Assign(BiTree &T,char e,char value){
//初始条件:二叉树T存在,e是T中某个结点。
//操作结果:结点e赋值为value。
 BiTree a;
 a=Point(T,e);
 a->data=value;
}

void InsertChild(BiTree &T,BiTree p,int LR,BiTree c){
//初始条件:二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空。
//操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点原有左或右子树成为c的右子树。
 if(T){
  if(LR==0){
   c->Rchild=p->Lchild;
   p->Lchild=c;
  }
  else{
   c->Rchild=p->Rchild;
   p->Rchild=c;
  }
 }
}
   
void DeleteChild(BiTree &T,BiTree p,int LR){
//初始条件:二叉树T存在,p指向T中某个结点,LR为0或1。
//操作结果:根据LR为0或1,删除T中p所指结点的左或右子树。
 if(T){
  if(p){
   if(LR==0)
    ClearBiTree(p->Lchild);
   else
    ClearBiTree(p->Rchild);
  }
 }
}

void ChangeLR(BiTree &T){
//将二叉树中所有结点的左、右子树相互交换
 BiTree a;
 if(T){
  if(T->Lchild)
   ChangeLR(T->Lchild);//使左子树完成改变
  if(T->Rchild)
   ChangeLR(T->Rchild);//使右子树完成改变
  if(T->Lchild && T->Rchild){//交换左右子树
   a=T->Lchild;
   T->Lchild=T->Rchild;
   T->Rchild=a;
  }
  else if(T->Lchild){
   T->Rchild=T->Lchild;
   T->Lchild=NULL;
  }
  else if(T->Rchild){
   T->Lchild=T->Rchild;
   T->Rchild=NULL;
  }
  else
   ;
 }
}


/********************main基本操作运用**********************/
int main()
{
 BiTree T;
 char e;
 InitBiTree(T);
 printf("创建二叉树,请输入根结点/n");
 CreateBiTree(T);
 printf("/n您创建的二叉树,先序遍历结果为:");
 PreOrderTraverse(T);
 printf("/n您创建的二叉树,中序遍历结果为:");
 InOrderTraverse(T);
 printf("/n您创建的二叉树的深度为:%d,根为%c/n",BiTreeDepth(T),Root(T));
 printf("请输入您要查看的结点:");
 scanf("%c",&e);
 printf("%c的双亲是%c,左兄弟是%c,右兄弟是%c,左孩子是%c,右孩子是%c/n",e,Parent(T,e),LeftSibling(T,e),RightSibling(T,e),LeftChild(T,e),RightChild(T,e));
   
 ChangeLR(T);
 printf("/n您改变后的二叉树,先序遍历结果为:");
 PreOrderTraverse(T);
 getchar();
 printf("/n请输入您要查看的结点:");
 scanf("%c",&e);
 printf("%c的双亲是%c,左兄弟是%c,右兄弟是%c,左孩子是%c,右孩子是%c/n",e,Parent(T,e),LeftSibling(T,e),RightSibling(T,e),LeftChild(T,e),RightChild(T,e));


 DestroyBiTree(T);
    system("pause");
 return 0;
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值