数据结构二叉树的基本操作的实现

一、实验目的
(1)掌握二叉树的逻辑结构;
(2)掌握二叉树的二叉链表存储结构;
(3)掌握基于二叉链表存储的二叉树的遍历操作的实现。
二、实验内容
(1)建立一棵含有n个结点的二叉树,采用二叉链表存储;
(2)前序(或中序、后序)遍历该二叉树。
(3)统计该二叉树中叶子个数。
(4)统计该二叉树中结点个数。
(5)求该二叉树的深度。
要求:
(1)设计菜单,根据菜单提示进行操作。
(2)按先序遍历序列创建二叉树的二叉链表。
注:二叉树的遍历一般采用递归算法,只要涉及到递归,一定会使用堆栈来实现。虽然在程序中看不到具体的堆栈,但可以通过观察函数调用的关系来理解认识堆栈。堆栈是实现二叉树遍历的最基本的数据结构。
三、算法设计
1、先序遍历递归建立二叉树

步骤

  1. 扫描字符序列, 读入字符ch
  2. 如果ch是一个 "#" 字符, 则表明该二叉树为空树, 即BTNULL; 3. 否则执行以下操作:
    申请一个结点空间BT;
    ch赋给BT-> data;
    递归创建BT的左子树;
    递归创建BT的右子树;

算法

void CreateBiTree(BiTree &BT){
	if(ch=='#')
	     BT = NULL;
	else{
       BT = new BiTNode;
       BT->data = ch;
       CreateBiTree (BT->Lchild);
       CreateBiTree (BT->Rchild);
	}
}
2、遍历二叉树
2.1 先序遍历

步骤
若二叉树为空,则空操作;
否则 :

  1. 访问根结点;
  2. 先序遍历左子树;
  3. 先序遍历右子树

算法

void PreOrder(BiTree &BT){
	if(BT){
        Visit(BT);
        PreOrder(BT->Lchild);
        PreOrder(BT->Rchild);
     }
}
2.2 中序遍历

步骤
若二叉树为空,则空操作;
否则

  1. 中序遍历左子树;
  2. 访问根结点;
  3. 中序遍历右子树。
    算法
void InOrder(BiTree BT){
    if(BT){
        InOrder(BT->Lchild);
        Visit(BT);
        InOrder(BT->Rchild);
    }
}
2.3 后序遍历

步骤
若二叉树为空,则空操作;
否则

  1. 后序遍历左子树;
  2. 后序遍历右子树;
  3. 访问根结点。

算法

void PostOrder(BiTree BT){
    if(BT){
        PostOrder(BT->Lchild);
        PostOrder(BT->Rchild);
        Visit(BT);
    }
}
3、统计二叉树叶子结点个数

步骤

  • 如果是空树,则结点个数为 0;
  • 如果只有根结点则就1个叶子结点;
  • 否则,结点个数为左子树的叶子结点个数加上右子树的叶子结点个数。

算法

int LeafCount(BiTree &BT){
    if(!BT)
        return ERROR;
    if(!BT->Lchild&&!BT->Rchild)
        return OK;
    return(LeafCount(BT->Lchild)+LeafCount(BT->Rchild));
}
4、交换二叉树左右子树

算法

void ChangeLR(BiTree BT){
    BiTree St;
    if(BT){
        ChangeLR(BT->Lchild);
        ChangeLR(BT->Rchild);
        St = BT->Lchild;
        BT->Lchild = BT->Rchild;
        BT->Rchild = St;
    }
}
5、统计二叉树中结点的总数

步骤

  • 如果是空树,则结点个数为 0;
  • 否则,结点个数为左子树的结点个数加上右子树的结点个数再加上 1 。

算法

int NodeCount(BiTree BT){
    if(!BT)
        return ERROR;
	else
    	return(NodeCount(BT->Lchild)+NodeCount(BT->Rchild)+1);
}
6、求二叉树的深度

步骤
如果是空树,递归结束,深度为0;
否则执行以下操作:

  • 递归计算左子树的深度记为m;
  • 递归计算右子树的深度记为n;
  • 如果 m 大于 n, 二叉树的深度为 m+1, 否则为 n+1。

算法

int Depth(BiTree BT){
    int h1,h2;
    if(BT==NULL)
        return ERROR;
    h1 = Depth(BT->Lchild);
    h2 = Depth(BT->Rchild);
    if(h1>h2)
        return(h1 + 1);
    else
        return(h2 + 1);
}
四、运行结果

在这里插入图片描述

五、代码实现
#include<stdio.h>
#include<stdlib.h>
#define ERROR 0
#define OK 1
#define TElemType char
typedef struct BiTNode{
    TElemType data;
    struct BiTNode *Lchild,*Rchild;
}BiTNode,*BiTree;

//显示根结点
void Visit(BiTree BT){
    printf("%c",BT->data);
}

//先序遍历
void PreOrder(BiTree BT){
    if(BT){
        Visit(BT);
        PreOrder(BT->Lchild);
        PreOrder(BT->Rchild);
    }
}

//中序遍历
void InOrder(BiTree BT){
    if(BT){
        InOrder(BT->Lchild);
        Visit(BT);
        InOrder(BT->Rchild);
    }
}

//后序遍历
void PostOrder(BiTree BT){
    if(BT){
        PostOrder(BT->Lchild);
        PostOrder(BT->Rchild);
        Visit(BT);
    }
}

//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树
void CreateBiTree(BiTree &BT){
    char ch;
	scanf("%c",&ch);
    if(ch!='#'){
    	BT =new BiTNode;
//    	if(!BT)
//			exit(-1);
        BT->data = ch;
        CreateBiTree(BT->Lchild);
        CreateBiTree(BT->Rchild);
	}
    else{
        BT = NULL;
    }
}

//统计二叉树中叶子结点的个数
int LeafCount(BiTree &BT){
    if(!BT)
        return ERROR;
    if(!BT->Lchild&&!BT->Rchild)
        return OK;
    return(LeafCount(BT->Lchild)+LeafCount(BT->Rchild));
}

//交换二叉树的左右子树
void ChangeLR(BiTree BT){
    BiTree St;
    if(BT){
        ChangeLR(BT->Lchild);
        ChangeLR(BT->Rchild);
        St = BT->Lchild;
        BT->Lchild = BT->Rchild;
        BT->Rchild = St;
    }
}

//统计二叉树中结点的总数
int NodeCount(BiTree BT){
    if(!BT)
        return ERROR;
	else
    	return(NodeCount(BT->Lchild)+NodeCount(BT->Rchild)+1);
}

//求二叉树的深度
int Depth(BiTree BT){
    int h1,h2;
    if(BT==NULL)
        return ERROR;
    h1 = Depth(BT->Lchild);
    h2 = Depth(BT->Rchild);
    if(h1>h2)
        return(h1 + 1);
    else
        return(h2 + 1);
}

//销毁二叉树
void DestroyBiTree(BiTree BT){
    if(!BT)return;
    DestroyBiTree(BT->Lchild);
    DestroyBiTree(BT->Rchild);
    delete BT;
}

void Showmenu(){
    printf("\n");
    printf("     --二叉树基本操作运算--    \n");
    printf("******************************\n");
    printf("*     1---建立二叉树         *\n");
    printf("*     2---先序遍历           *\n");
    printf("*     3---中序遍历           *\n");
    printf("*     4---后序遍历           *\n");
    printf("*     5---统计叶子数         *\n");
    printf("*     6---统计结点数         *\n");
    printf("*     7---求二叉树深度       *\n");
    printf("*     8---交换左右子树       *\n");
    printf("*     0---退出               *\n");
    printf("*****************************\n");
    printf("请选择菜单号(0-8):");
}

void binaryOP(){
    BiTree BT;
    int count = 0;
    int choice;
    while(choice){
        Showmenu();
        scanf("%d",&choice);
        switch(choice){
            case 1:
                printf("按先序输入二叉树结点序列:\n");//以#结束
                CreateBiTree(BT);
                printf("二叉树建立成功!\n");
                break;
            case 2:
                if(BT == NULL){
                    printf("空树!\n");
                }
                else{
                    printf("先序遍历序列为:");
                    PreOrder(BT);
                }
                break;
            case 3:
                if(BT == NULL){
                    printf("空树!\n");
                }
                else{
                    printf("中序遍历序列为:");
                    InOrder(BT);
                }
                break;
            case 4:
                if(BT == NULL){
                    printf("空树!\n");
                }
                else{
                    printf("后序遍历序列为:");
                    PostOrder(BT);
                }
                break;
            case 5:
                count = LeafCount(BT);
                printf("该二叉树有%d个叶子结点。\n",count);
                break;
            case 6:
                count = NodeCount(BT);
                printf("该二叉树有%d个结点。\n",count);
                break;
            case 7:
                printf("该二叉树的深度为%d !\n",Depth(BT));
                break;
            case 8:
                ChangeLR(BT);
                printf("交换成功!\n");
                printf("先序序列为:\n");
                PreOrder(BT);
                break;
            case 0:
                printf("程序结束!\n");
                break;
        }
    }
}

int main(){
    binaryOP();
    return 0;
}

作者文坛写于 2020年5月21日

  • 10
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tan-1210

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值