二叉树的操作

来源:互联网 发布:js代码格式化 编辑:程序博客网 时间:2024/04/29 12:57

#include <stdlib.h>
#include <stdio.h>
#define queuesize 100
#define null 0
typedef char datatype;
typedef struct node{
  datatype data;
  struct node *lchild,*rchild;
 }bintnode;//定义二叉链表结点结构
typedef bintnode *bintree;//定义二叉链表指针类型

typedef struct{
  int front,rear;
  bintree data[queuesize];//循环队列元素类型为二叉链表结点指针
  int count;
 }cirqueue;//循环队列结构定义

main()//主函数
 {//建立二叉树的二叉链表表示,并进行先序遍历、中序遍历、后序遍历和按层次遍历,
  //求出所有叶子和结点总数。
  bintree t=null;
  int n;
  printf("please input nodes of bintree:/n");
  createbintree(&t);//建立二叉链表

  printf("the preorder is:");
  preorder(t);//对二叉树t进行先序遍历
  printf("/n");

  printf("the inorder is:");
  inorder(t);//对二叉树t进行中序遍历

  printf("/nthe postorder is:");
  postorder(t);//对二叉树t进行后序遍历

  printf("/nthe leverorder is:");
  leverorder(t);//对二叉树t进行按层次遍历

  n=leave(t);// 求出二叉树的叶子数n

  printf("/nthe leave of bintree is: %d",n);//打印二叉树的叶子总数
  if (n){//当叶子数不为0
    printf("/nthe list of leave is:"); 
    leavelist(t);//输出所有的叶子
   }
  else 
    printf("/nno leave!");//输出无叶子(即空树)信息
  printf("/nthe nodes of bintree is: %d/n",nodes(t));//输出二叉树的总结点数
 }

createbintree(bintree *t)
 {//输入二叉树的先序遍历序列,创建二叉链表
  char ch;
  if ((ch=getchar())==' ')//如果读入空格字符,创建空树
     *t=null;
  else{
     *t=(bintnode*)malloc(sizeof(bintnode));//申请根结点*t空间
     (*t)->data=ch;//将结点数据ch放入根结点的数据域
     createbintree(&(*t)->lchild);//建左子树
     createbintree(&(*t)->rchild);//建右子树
    }//end of if
 }//end of creatbintree

preorder(bintree t)
 {//对二叉树进行先序遍历
  if (t){
   printf("%c",t->data);
   preorder(t->lchild);
   preorder(t->rchild);
  }//end of if
 }//end of preorder
 
inorder(bintree t)
 {//对二叉树进行中序遍历
  if (t){
       inorder(t->lchild);
       printf("%c",t->data);
       inorder(t->rchild);
     }//end of if
 }//end of inorder

postorder(bintree t)
 {//对二叉树进行后序遍历
  if (t){
      postorder(t->lchild);
      postorder(t->rchild);
      printf("%c",t->data);
     }//end of if
 }//end of postorder

error(char *message)
 {//出错时,调用的返回出错信息,终止程序运行的函数
   fprintf(stderr,"error:%s/n",message);
   exit(1);
 }

leverorder(bintree t)
 {
  cirqueue *q;
  bintree p;
  q=(cirqueue*)malloc(sizeof(cirqueue));//申请循环队列空间
  q->rear=q->front=q->count=0;//将循环队列初始化为空
  q->data[q->rear]=t;q->count++;q->rear=(q->rear+1)%queuesize;//将根结点入队
  while (q->count)//若队列不为空,做以下操作
    if (q->data[q->front]){//当队首元素不为空指针,做以下操作
      p=q->data[q->front];//取队首元素*p
      printf("%c",p->data);//打印*p结点的数据域信息
      q->front=(q->front+1)%queuesize;q->count--;//队首元素出队
      if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行
         error("the queue full!");
      else{//若队列不满,将*p结点的左孩子指针入队
         q->count++;q->data[q->rear]=p->lchild;
         q->rear=(q->rear+1)%queuesize;
        }//enf of if
      if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行
         error("the queue full!");
      else{//若队列不满,将*p结点的右孩子指针入队
          q->count++;q->data[q->rear]=p->rchild;
          q->rear=(q->rear+1)%queuesize;
        }//end of if
     }//end of if 
    else{//当队首元素为空指针,将空指针出队
       q->front=(q->front+1)%queuesize;q->count--;}
 }//end of leverorder


int leave(bintree t)
 {//求以t为树根的二叉树的叶子总数
  if (!t)//若根结点为
   return 0;//返回叶子数0
  else//若根结点非空 
   if ((t->lchild==null)&&(t->rchild==null))//若根结点的左、右孩子都为空
     return 1;//返回叶子数1
   else //根结点的左、右孩子有1个不为空
     return(leave(t->lchild)+leave(t->rchild));
       //叶子数为左子树的叶子数加右子树中的叶子数
 }

leavelist(bintree t)
 {
  if (t){
    leavelist(t->lchild);//输出左子树中的所有叶子
    if ((t->lchild==null)&&(t->rchild==null))
      //若根结点为叶子,则输出叶子的数据域信息
      printf("%c",t->data);
      leavelist(t->rchild);//输出右子树中的所有叶子
     }//end of if
 }//end of inorder

int nodes(bintree t)
 {
  if (!t)//若二叉树为空树 
    return 0;//返回结点数0
  else //若二叉树非空
    return nodes(t->lchild)+nodes(t->rchild)+1;
      //二叉树的结点总数为左、右子树的结点总数加上1(根结点)
 }//end of node

原创粉丝点击