完全二叉树的判定

/*先要对二叉树进行层次遍历,在遍历过程中对每一个结点进行检查:    
  (1)如果当前结点没有右子树,则剩下的全部结点必须既没有左子树,又没有右子树;    
  (2)如果当前结点有右子树,则它必须也有左子树.    
   
  如果同时满足(1)(2),则是完全二叉树;否则不是.    
   
  对二叉树进行层次遍历需要使用队列结构.    
  */    
   
  #include   <stdio.h>    
  #include   <malloc.h>    
   
  #define   true   1    
  #define   false   0    
  typedef   int   bool;    
   
  typedef   char   datatype;    
  typedef   struct   _node    
  {    
  datatype   data;    
  struct   _node   *pleft;    
  struct   _node   *pright;    
  }   node;    
   
  /*队列*/    
  typedef   struct    
  {    
  bool   bisempty;    
  int   nfront;    
  int   nrear;    
  int   nsize;    
  node   **pdata;    
  }   queue;    
   
  /*队列初始化。nsize   =   数组大小*/    
  void   initqueue(queue   *pque,   int   nsize)    
  {    
  pque->pdata   =   (node   **)malloc(sizeof(node   *)   *   nsize);    
  pque->nsize   =   nsize;    
  pque->nfront   =   pque->nrear   =   0;    
  pque->bisempty   =   true;    
  }    
   
  /*入队列*/    
  bool   inqueue(queue   *pque,   node   *data)    
  {    
  if   (pque->bisempty   ||   pque->nrear   !=   pque->nfront)   /*判断队列是否满*/    
  {    
  pque->bisempty   =   false;    
  pque->pdata[pque->nrear]   =   data;    
  pque->nrear++;    
  if   (pque->nrear   ==   pque->nsize)    
  pque->nrear   =   0;    
  return   true;    
  }    
  else    
  return   false;    
  }    
   
  /*出队列。pdatabfr为容纳数据的变量的指针*/    
  bool   outqueue(queue   *pque,   node   **pdatabfr)    
  {    
  if   (pque->bisempty)    
  return   false;    
  else    
  {    
  *pdatabfr   =   pque->pdata[pque->nfront];    
  pque->nfront++;    
  if   (pque->nfront   ==   pque->nsize)    
  pque->nfront   =   0;    
  if   (pque->nfront   ==   pque->nrear)    
  pque->bisempty   =   true;    
  return   true;    
  }    
  }    
   
  /*二叉树的层次遍历并判断是否为完全二叉树*/    
  bool   leveltraverse(node   *proot)    
  {    
  bool   bresult   =   true;    
  bool   bcomfine   =   false;    
  node   *pcurnode;    
  queue   que;    
   
  if   (proot   ==   null)    
  return   true;    
   
  initqueue(&que,1024);   /*这里不考虑队列溢出,在应用中应根据实际情况使用合适    
  的队列*/    
  inqueue(&que,proot);    
   
  while   (outqueue(&que,&pcurnode))    
  {    
  if   (!pcurnode->pleft   &&   pcurnode->pright)    
  {    
  bresult   =   false;    
  break;    
  }    
  if   (bcomfine   &&   (pcurnode->pleft   ||   pcurnode->pright))    
  {    
  bresult   =   false;    
  break;    
  }    
  if   (pcurnode->pleft)    
  inqueue(&que,pcurnode->pleft);    
  if   (pcurnode->pright)    
  inqueue(&que,pcurnode->pright);    
  else    
  bcomfine   =   true;    
  }    
  return   bresult;    
  }    
   
  /*简单的测试环境*/    
   
  /*   从键盘缓冲区中读取一个不为空格且不为回车的字符   */    
  char   getnextchar(void)    
  {    
  char   ch;    
  do    
  {    
  ch   =   getchar();    
  }   while   (ch   ==       ||   ch   ==   /n);    
  return   ch;    
  }    
   
  /*利用前序遍历序列建立二叉树。扩充结点用‘*’代表。前序序列从键盘输入*/    
  void   createtree(node   *root)    
  {    
  root->pleft   =   root->pright   =   null;    
  if   (root->data   !=   *)   /*   如果不为扩充结点,   要建立左结点和右结点   */    
  {    
  root->pleft   =   (node   *)malloc(sizeof(node));    
  root->pleft->data   =   getnextchar();    
  createtree(root->pleft);    
  root->pright   =   (node   *)malloc(sizeof(node));    
  root->pright->data   =   getnextchar();    
  createtree(root->pright);    
  }    
  }    
   
  /*除去*结点*/    
  void   trimtree(node   *proot)    
  {    
  if   (proot->pleft)    
  if   (proot->pleft->data   ==   *)    
  {    
  free(proot->pleft);    
  proot->pleft   =   null;    
  }    
  else    
  trimtree(proot->pleft);    
  if   (proot->pright)    
  if   (proot->pright->data   ==   *)    
  {    
  free(proot->pright);    
  proot->pright   =   null;    
  }    
  else    
  trimtree(proot->pright);    
  }    
   
  void   main()    
  {    
  node   root;    
   
  root.data   =   getnextchar();    
  createtree(&root);    
  trimtree(&root);    
   
  printf("%d/n",leveltraverse(&root));    
  }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值