基于递归调用的二叉树建立、遍历算法实现与应用示例

《数据结构》课程中,基于递归调用的二叉树的3种遍历算法及其应用是一项重要内容。本文在编程实现基于递归调用的遍历二叉树常用的3种算法之前,先使用先序遍历扩展序列来创建二叉树,再依次使用3种基于递归的遍历算法来输出各自的遍历结果,并进行2种基本应用:统计叶子结点、计算二叉树高度,将这些算法汇总之后写出基于简单图形界面的程序,其运行结果示例及详细代码分别如下所示:

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

# define OK 1
# define OVERFLOW -2

typedef int Status;

typedef char BiTreeElemType;

typedef struct BiTreeNode{
    BiTreeElemType data;
    struct BiTreeNode *LChild, *RChild;
}BiTreeNode,*BiTree;

//按先序扩展序列创建二叉树 
Status CreateBiTree(BiTree *T)
{
    BiTreeElemType data;    
    scanf("%c",&data);
    if (data == '#')
        *T = NULL;
    else 
        {
            *T = (BiTreeNode *) malloc(sizeof(BiTreeNode));
            if (*T == NULL) exit(OVERFLOW);
            (*T)->data = data;
            CreateBiTree(&(*T)->LChild);
            CreateBiTree(&(*T)->RChild);
        }
    return OK;
}

// 其它选项界面 
void InterfaceOfChoice()
{
    int i;
    printf("\n ");
    for(i=0; i<40; i++)
        printf("-");
    printf("\n|           0--退出系统                     |");
    printf("\n|           1--先序遍历                     |");
    printf("\n|           2--中序遍历                     |");
    printf("\n|           3--后序遍历                     |");
    printf("\n|           4--统计叶子结点数          |");
    printf("\n|           5--计算二叉树高度          |\n ");         
    for(i=0;i<40;i++)
        printf("-");
}

// 先序递归遍历输出: 
void PreOrder(BiTree T)
{
    if(T)
    {
        printf("%c",T->data);
        PreOrder(T->LChild);
        PreOrder(T->RChild);    
    }
}

// 中序递归遍历输出:
void InOrder(BiTree T)
{
    if(T)
    {
        InOrder(T->LChild);
        printf("%c",T->data);
        InOrder(T->RChild);    
    }
}

// 后序递归遍历输出:
void PostOrder(BiTree T)
{
    if(T)
    {
        PostOrder(T->LChild);        
        PostOrder(T->RChild);
        printf("%c",T->data);    
    }
}

// 统计二叉树叶子结点个数 
int CountLeaf(BiTree T)
{
    int count;
    if(T == NULL)
        count = 0;
    else if(T->LChild == NULL && T->RChild == NULL)
        count = 1;
    else
        count = CountLeaf(T->LChild) + CountLeaf(T->RChild);
    return count;
}

// 计算二叉树高度 
int CalHeight(BiTree T)
{
    int height, hl, hr;
    if(T == NULL)
        height = 0;
    else
        {
            hl = 1 + CalHeight(T->LChild);
            hr = 1 + CalHeight(T->RChild);
            height = (hl>hr?hl:hr);
        }
    return height;
}
 
// 主程序 
int main()
{
    // 按先序扩展序列输入数据来创建二叉树 
    BiTreeNode *t = NULL;    
    int result;
    char choice;//后续用于用户选择数字序号 
    printf("\n请按先序序列输入各结点字符来创建二叉树,子树为空时输入'#'表示(如:AB##C#D##):");     
    result = CreateBiTree(&t);            
    if (result == 1 && t)
        printf("\n恭喜您,二叉树创建成功!\n");
    else if (!t)
        {
            printf("\n该二叉树是空树!\n");
            exit(0);             
        }
    else
        printf("\n对不起,二叉树创建失败!\n");
    
    // 选择其它操作序号并回车执行:    
    InterfaceOfChoice();    
    printf("\n请输入要选择的其它操作对应的数字序号(0-5):");            
    // 根据用户输入的序号来选择不同的分支执行对应操作,直到输入'0'结束程序:
    scanf(" %c",&choice);    //注意:%c前面要留有空格,目的是防止读入前面的回车符 
    while(choice != '0')
        {
            if(choice < '0' || choice >= '6')
                printf("\n请重新输入正确的数字序号:");                
            else
                {
                    switch(choice)
                        {
                            case '1':printf("\n二叉树的先序序列为:"); PreOrder(t); break;
                            case '2':printf("\n二叉树的中序序列为:"); InOrder(t); break; 
                            case '3':printf("\n二叉树的后序序列为:"); PostOrder(t); break;
                            case '4':printf("\n二叉树的叶子结点个数为:%d", CountLeaf(t)); break;
                            case '5':printf("\n二叉树的高度为:%d", CalHeight(t)); break;
                        }
                    printf("\n请输入要选择的其它操作对应的数字序号(0-5):");                                            
                }
            scanf(" %c",&choice);                
        }     
    printf("程序结束,再见!");
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值