二叉树的创建和遍历

21 篇文章 2 订阅
2 篇文章 0 订阅

一、实验目的:

1、熟悉二叉树结点的结构和对二叉树的基本操作;

2、掌握对二叉树每一种操作的具体实现;

3、学会递归方法和非递归方法实现二叉树的运算某重操作。

 

二、实验内容:

1、建立一棵二叉树。

2、用递归算法对二叉树进行先序、中序和后序遍历。

3、用非递归算法对二叉树进行先序、中序和后序遍历。

 

三、实验要求:

   编写实现二叉树建立和遍历的基本算法的函数,并在此基础上设计一个主程序完成如下功能:

   ⑴定义二叉树的二叉链表存储结构;

   ⑵以扩展先序遍历序列建立二叉树的二叉链表;

   ⑶用递归算法分别实现二叉树的先序、中序和后续遍历,并打印输出;

   ⑷用非递归算法分别实现二叉树的先序、中序和后续遍历,并打印输出;

   ⑸计算二叉树的高度;

   ⑹计算二叉树叶子节点的个数。

  输入格式为用.代表空,0为结束符。例如:12..34..5..0

代码如下:

#include <stdio.h>
#include <stdlib.h>
#define MAXNODE 100
typedef char ElemType;
typedef struct BiTreeNode
{
    ElemType data;
    struct BiTreeNode *lchild;
    struct BiTreeNode *rchild;
}BiTreeNode, *BiTree;
//创建二叉树 
BiTree CreateBiTree(char str[])
{
    BiTree bt;
    char ch;
    static int i = 0;
    ch = str[i++];
    if (ch == '.')
        bt = NULL;        //创建空树
    else
    {
        bt = (BiTree)malloc(sizeof(BiTreeNode));
        bt->data = ch;        //创建根节点
        bt->lchild = CreateBiTree(str);        //创建左子树
        bt->rchild = CreateBiTree(str);        //创建右子树
    }
    return bt;
}

void PreOrder(BiTree bt)        //bt为指向根结点的指针
{
    if (bt != NULL)
    {
        printf("%c", bt->data);        //访问根节点
        PreOrder(bt->lchild);        //先序遍历左子树
        PreOrder(bt->rchild);        //遍历右子树
    }
}

void InOrder(BiTree bt)
{
    if (bt != NULL)
    {
        InOrder(bt->lchild);        //中序遍历左子树    
        printf("%c", bt->data);        //访问根节点
        InOrder(bt->rchild);        //遍历右子树
    }
}

void PostOrder(BiTree bt)
{
    if (bt != NULL)
    {
        PostOrder(bt->lchild);        //后序遍历左子树    
        PostOrder(bt->rchild);         //遍历右子树
        printf("%c", bt->data);        //访问根节点

    }
}

int BitreeLeaf(BiTree bt)
{
    if (bt == NULL)
        return 0;
    if (bt->lchild == NULL && bt->rchild == NULL)
        //只有一个根节点
        return 1;
    else
        return (BitreeLeaf(bt->lchild) + BitreeLeaf(bt->rchild));
}

int max(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    else
    {
        return b;
    }

}
int BitreeDepth(BiTree bt)
{
    int d = 0, depthL, depthR;    //depthL,depthR分别表示左右子树深度
    if (bt == NULL)
        return 0;            //空树,深度为0
    depthL = BitreeDepth(bt->lchild);
    depthR = BitreeDepth(bt->rchild);
    d = max(depthL, depthR);
    return d + 1;
}


//非递归先序遍历
void preOrder(BiTree bt)
{
    BiTree s[MAXNODE], p = bt;
    int top = -1;
    if (p == NULL)return;
    do{
        while (p != NULL)
        {
            if (top >= MAXNODE - 1)
            {
                printf("栈溢出\n");
                return;
            }
            printf("%c", p->data);
            s[++top] = p;
            p = p->lchild;
        }
        if (top == -1)return;
        else
        {
            p = s[top--];
            p = p->rchild;
        }
    } while (p != NULL || top != -1);
}

//非递归中序遍历 
void inOrder(BiTree bt)
{
    BiTree s[MAXNODE], p = bt;
    int top = -1;
    if (p == NULL)return;
    do{
        while (p != NULL)
        {
            if (top >= MAXNODE - 1)
            {
                printf("栈溢出\n");
                return;
            }
            s[++top] = p;
            p = p->lchild;
        }
        if (top == -1)return;
        else
        {
            p = s[top--];
            printf("%c", p->data);        //访问根节点
            p = p->rchild;
        }
    } while (p != NULL || top != -1);
}

//非递归后序遍历 
void postOrder(BiTree T)
{
    BiTree s[MAXNODE];
    int top = -1;
    BiTree p = T, r = NULL;

    while (p || top > -1)
    {
        if (p) {  //走到最左边 
            s[++top] = p;
            p = p->lchild;
        }
        else {  //向右
            p = s[top];  //取栈顶元素 
            if (p->rchild && p->rchild != r) { //右子树不空,且未陪访问 
                p = p->rchild;  //转向右 
                s[++top] = p;   //压栈 
                p = p->lchild;  //再走到最左 
            }
            else {   //否则弹出栈,并访问 
                p = s[top--];//出栈,并获得栈顶元素
                printf("%c", p->data);
                r = p;   //记录最近访问过的结点 
                p = NULL; //结点访问过,重置p指针 
            }
        }
    }
}

 

//菜单界面
void menu()
{
    system("cls");
    printf("\n");
    printf("\t\t---------------欢迎使用二叉树的创建和遍历--------------------------------\n");
    printf("\t\t|\t\t a 用递归算法分别实现二叉树的先序遍历       \t\t|\n");
    printf("\t\t|\t\t b 用递归算法分别实现二叉树的中序遍历       \t\t|\n");
    printf("\t\t|\t\t c 用递归算法分别实现二叉树的后续遍历       \t\t|\n");
    printf("\t\t|\t\t d 用非递归算法分别实现二叉树的先序遍历     \t\t|\n");
    printf("\t\t|\t\t e 用非递归算法分别实现二叉树的中序遍历     \t\t|\n");
    printf("\t\t|\t\t f 用非递归算法分别实现二叉树的后续遍历     \t\t|\n");
    printf("\t\t|\t\t g 计算二叉树的高度                            \t\t|\n");
    printf("\t\t|\t\t h 计算二叉树叶子节点的个数                 \t\t|\n");
    printf("\t\t|\t\t i 退出系统                                 \t\t|\n");
    printf("\t\t-------------------------------------------------------------------------\n");
    printf("\t\t请选择(a-i):");
}

int main()
{
    BiTree bt;
    //BiTree *p = (BiTree *)malloc(sizeof(BiTree));
    int deepth, num = 0;
    int quit = 0;
    char arr[50];
    int i = 0;
    char select;
    printf("以扩展先序遍历序列建立二叉树:");
    scanf("%c", &arr[i]);
    while (arr[i] != '0'&&i<50)
    {
        i++;
        scanf("%c", &arr[i]);
    }
    bt = CreateBiTree(arr);
    getchar();
    while (1)
    {
        menu();            //调用子函数
        scanf("%c", &select);
        switch (select)
        {
        case 'a':    printf("遍历结果为:");
                    PreOrder(bt);
                    printf("\n");
                    break;
        case 'b':    printf("遍历结果为:");
                    InOrder(bt);
                    printf("\n");
                    break; 
        case 'c':    printf("遍历结果为:");
                    PostOrder(bt);
                    printf("\n");
                    break; 
        case 'd':   printf("遍历结果为:");
                    preOrder(bt);
                    printf("\n");
                    break;
        case 'e':   printf("遍历结果为:");
                    inOrder(bt);
                    printf("\n");
                    break;  
        case 'f':   printf("遍历结果为:");
                    postOrder(bt);
                    printf("\n");
                    break;
        case 'g':    deepth = BitreeDepth(bt);
                    printf("树的深度为:%d\n", deepth); 
                    break;
        case 'h':    num = BitreeLeaf(bt);
                    printf("树的叶子结点个数为:%d\n", num);
                    break;
        case 'i': quit = 1; break;
        default:printf("请输入a~i之间的数字\n"); break;
        }
        if (quit == 1)
        {
            break;
        }
        printf("按任意键返回主菜单!\n");
        getchar();                //提取到缓冲区中的回车键
        getchar();                //起到暂停的作用
        printf("程序结束!\n");
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值