二叉链表实现二叉树

/*
  Name: 二叉链表实现二叉树
  Copyright:
  Author:
  Date:
  Description:
*/

#ifndef BINTREE_H_INCLUDED
#define BINTREE_H_INCLUDED

#include <stdlib.h>
#include "ds.h"

//数据元素的缺省类型用char
#ifndef ElemType
#define ElemType char
#define ELEMTYPE_TAG
#endif
/*下面使用TElemType如同ElemType*/
#define TElemType ElemType

///
// 二叉链表类型
typedef struct BiTNode {
    TElemType data;
    struct BiTNode *lchild, *rchild; //左右孩子指针
} BiTNode, *BiTree;


///
// 二叉链表的基本操作

//新建二叉链表结点
BiTree MakeNode(TElemType e, BiTree lch, BiTree rch)
{
    BiTree p = (BiTree)malloc(sizeof(BiTNode));
    p->data = e;
    p->lchild = lch;
    p->rchild = rch;
    return p;
}

//按先序次序输入二叉树中的结点值(字符)构造二叉树
Status CreateBiTree(BiTree &T)
{
    char ch;
    read(ch); // NOTE: 这里用字符类型
    if( ch==' ' ) //空格代表空指针
        T = 0;
    else {
        //建立结点
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        //-------------------------------------
        // TODO (#1#):建立左子树和右子树
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
        //-------------------------------------
    }
    return OK;
}

//销毁二叉树
Status DestroyBiTree(BiTree &T)
{
    //-------------------------------------
    // TODO (#1#): 销毁二叉树,释放所有结点
 if(!T)
  return ERROR;
 else{
  DestroyBiTree(T->lchild);
     DestroyBiTree(T->rchild);
  free(T);
 }
 return OK;
    //-------------------------------------
}

//先序遍历二叉树T,对每个结点数据调用Visit函数
Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 先序遍历二叉树
   if(!T)
    return OK;
   else{
    Visit(T->data);
    PreOrderTraverse(T->lchild,Visit);
    PreOrderTraverse(T->rchild,Visit);
    return OK;
   }
   return ERROR;
    //-------------------------------------
}

//中序遍历二叉树T,对每个结点数据调用Visit函数
Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 中序遍历二叉树
   if(!T)
    return OK;
   else{   
    InOrderTraverse(T->lchild,Visit);
    Visit(T->data);
    InOrderTraverse(T->rchild,Visit);
    return OK;
   }
   return ERROR; //-------------------------------------
}

//后序遍历二叉树T,对每个结点数据调用Visit函数
Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 后序遍历二叉树
   if(!T)
    return OK;
   else{   
    PostOrderTraverse(T->lchild,Visit);
    PostOrderTraverse(T->rchild,Visit);
    Visit(T->data);
    return OK;
   }
   return ERROR; //-------------------------------------
}

//按层次顺序遍历二叉树T,对每个结点数据调用Visit函数
Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 按层次遍历二叉树
 BiTree  Q[100];
 int front=0,rear=0;

 if(!T)
  return ERROR;
 else
 {
  Visit(T->data);
  Q[rear]=T;  rear=(rear+1)%100;
  while(front!=rear){
   BiTree p=Q[front];
   front=(front+1)%100;
   if(p->lchild){
    Visit(p->lchild->data);
    Q[rear]=p->lchild; 
    rear=(rear+1)%100;
   }
   if(p->rchild){
    Visit(p->rchild->data);
    Q[rear]=p->rchild; 
    rear=(rear+1)%100;
   }
  }
  return OK;
 }
 
}

//以直观方式打印二叉树
void PrintTree(BiTree t, int level=0)
{
    int i;
    if(t) {
        PrintTree(t->rchild, level+1);
        for(i=0; i<level; i++) printf("    ");
        write(t->data); write('\n');
        PrintTree(t->lchild, level+1);
    }
}

//取消缺省类型的定义以免影响其它部分
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif

#endif //BINTREE_H_INCLUDED

 

/****************************************************
  @Title: 数据结构实验
  @Name: <实验6-3> 遍历二叉树及其应用
  @Object:
      [实验目的]
          实现二叉树的二叉链表存储结构;
          实现先序、中序和后序遍历二叉树;
          遍历二叉树的应用:计算叶子结点,二叉树深度等
      [实验提示]
          1. 在 bintree.h 中实现二叉树的基本操作         
          2. 在 dsp0603.cpp 中编写应用遍历二叉树的算法          
  @Include:
      bintree.h [*]
          二叉树的二叉链表实现
  @Usage:
      请查看"TO-DO列表",根据要求完成代码
  @Copyright: BTC 2004, Zhuang Bo
  @Author: Zhuang Bo
  @Date: 2004
  @Description:
*****************************************************/

#include <stdio.h>
#include <stdlib.h>

#define ElemType char //二叉树中数据元素类型
#include "bintree.h"  //二叉树的实现

//打印结点数据(作为Visit函数)
Status print(char);
//计算二叉树中叶子结点的个数
int LeafCount(BiTree bt);
//计算二叉树的深度
int Deapth(BiTree bt);
//按缩进方式打印二叉树
void PrintTreeIndent(BiTree bt, int indent);

///
// 主程序
int main()
{
    BiTree bt = 0;
   
    //建立二叉树
    printf("建立二叉树(按先序输入二叉树中的结点,空格表示空树)\n");
    if( CreateBiTree(bt)==ERROR ) {
        printf("ERROR: call CreateBiTree\n");
        system("pause");
        exit(1);
    }
    PrintTree(bt);
   
    //遍历二叉树
    printf("\n先序遍历: ");
    if( PreOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call PreOrderTraverse\n");
    printf("\n中序遍历: ");
    if( InOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call InOrderTraverse\n");
    printf("\n后序遍历: ");
    if( PostOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call PostOrderTraverse\n");
    printf("\n按层遍历: ");
    if( LevelOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call LevelOrderTraverse\n");
   
    //二叉树的应用
    printf("\n二叉树中叶子结点的个数: %d\n", LeafCount(bt));
    printf("\n二叉树的深度: %d\n", Deapth(bt));
    printf("\n按缩进形式打印:\n");
    PrintTreeIndent(bt,1);
   
    //销毁二叉树
    DestroyBiTree(bt);

    system("pause"); //暂停以便查看结果
}


///
// 函数实现

//打印结点数据
Status print(char ch)
{
    putchar(ch);
    return OK;
}

//计算二叉树中叶子结点的个数
int LeafCount(BiTree bt)
{
    //-------------------------------------
    // TODO (#1#):计算二叉树中叶子结点的个数
 if(!bt)
  return 0;
 if(!bt->lchild&&!bt->rchild)
  return 1;
 
 int left=LeafCount(bt->lchild);
 int right=LeafCount(bt->rchild);
 return left+right;
 
  
}

//计算二叉树的深度
int Deapth(BiTree bt)
{
    //-------------------------------------
    // TODO (#1#):计算二叉树的深度
    if(!bt)
  return 0;
    else{
  int lh=Deapth(bt->lchild);
  int rh=Deapth(bt->rchild);
  return 1+((lh>rh)?lh:rh);
 }
}

//按缩进方式打印二叉树
void PrintTreeIndent(BiTree bt, int indent)
{
    //-------------------------------------
    // TODO (#1#):按缩进方式(凹入表示法)打印二叉树
   
       int i;

      if (bt)

      {
  for (i=1;  i<indent;  i++)  printf(" ");    //输出indent个空格

        printf("%c\n", bt->data);

        PrintTreeIndent (bt->lchild, indent+3);

        PrintTreeIndent (bt->rchild,  indent+3);

       }

}

 

/*
  Name: 类C通用模块
  Copyright: BTC 2004
  Author: Zhuang Bo
  Date: 2004
  Description: 
    [Constants]
       TRUE/FALSE/OK/ERROR/INFEASIBLE/OVERFLOW     
    [Types] 
       Status     
    [Functions]
       max(a,b)
       min(a,b)
       read(char/int/float/double/char*)
       write(char/int/float/double/char*)
*/

#ifndef _DS_H_
#define _DS_H_

// 函数结果状态代码
const int TRUE      = 1;
const int FALSE     = 0;
const int OK        = 1;
const int ERROR     = 0;
const int INFEASIBLE    = -1;
const int OVERFLOW      = -2;

// Status 是函数的类型,其值是函数结果状态代码
typedef int Status;

//基本函数
#define max(a,b) (((a)<(b))?(b):(a))
#define min(a,b) (((a)<(b))?(a):(b))

#include <stdio.h>
//不用格式串的输入输出(目的是为了方便书写算法)
//    比如输入一个基本类型(char, int, float, double, char*)的
//    变量 x,可以直接用 read(x);输入,而打印则用 write(x);。
//    对于自定义类型,可以继续扩充。
inline void read(char& e)     { e = getchar(); }
inline void read(int& e)      { scanf("%d", &e); }
inline void read(float& e)    { scanf("%f", &e); }
inline void read(double& e)   { scanf("%lf", &e); }
inline void read(char *e)     { gets(e); }
inline void write(char e)     { printf("%c", e); }
inline void write(int e)      { printf("%d", e); }
inline void write(float e)    { printf("%f", e); }
inline void write(double e)   { printf("%lf", e); }
inline void write(char *e)    { printf("%s",e); }

#endif  // _DS_H_

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值