遍历二叉树及其应用

主要代码

/****************************************************
  @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);
//无返回值打印叶子个数
void LeafCount2(BiTree bt,  int &count);
//交换左右子树
Status change(BiTree bt);

///////////////////////////////////////////////////////////
// 主程序 
void main()
{
    BiTree bt = 0;
    int count=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));
    LeafCount2(bt,count);
    printf("\n方法二求二叉树中叶子结点的个数%d",count);
    printf("\n二叉树的深度: %d\n", Deapth(bt));
    printf("\n按缩进形式打印:\n");
    PrintTreeIndent(bt,1);
    printf("\n交换左右子树以后打印效果\n");
    change(bt);
    PrintTree(bt);
    //销毁二叉树 
    DestroyBiTree(bt); 
    system("pause"); //暂停以便查看结果 
}


///////////////////////////////////////////////////////////
// 函数实现

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

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

}
void LeafCount2(BiTree bt, int &count)
{
    //-------------------------------------
    // TODO (#1#):计算二叉树中叶子结点的个数
    if(bt) {
    if(!(bt->lchild)&&!(bt->rchild)){
    count++;
    }
    LeafCount2(bt->lchild,count);
    LeafCount2(bt->rchild,count);
    }
}

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

//按缩进方式打印二叉树
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);
       }
    //-------------------------------------
}
//交换左右子树
Status change(BiTree bt){
    BiTree t;
    if(!bt){
        return ERROR;
    }
    t=bt->lchild;
    bt->lchild=bt->rchild;
    bt->rchild=t;
    change(bt->lchild);
    change(bt->rchild);
}

/*
  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));
        //if(!T){
        //  exit(0);
        //}
        //T->data = ch; 
        //-------------------------------------
        // TODO (#1#):建立左子树和右子树
        T=MakeNode(ch, NULL, NULL);
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
        //-------------------------------------
    }
    return OK;
}

//销毁二叉树
Status DestroyBiTree(BiTree &T)
{
    //-------------------------------------
    // TODO (#1#): 销毁二叉树,释放所有结点 
    return ERROR;
    //-------------------------------------
} 

//先序遍历二叉树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

演示效果图

这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章