.cpp环境下的二叉树创建与应用(数据结构)

共9个功能,包括创建,先序中序后序遍历,计算节点,清空二叉树,计算叶子个数,计算树的深度,返回节点指针位置。其中返回节点指针位置功能无法正常操作,请大佬指点。

代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct BiTNode {
	char data;
	struct BiTNode* LChild;
	struct BiTNode* RChild;
} BiTNode, * BiTree;

int CreateBiTree(BiTree &T) {
	char ch;
	//fflush(stdin);//吸收缓冲符
	rewind(stdin);//吸收缓冲区 rewind(stdin)替代fflush(stdin);
	scanf("%c", &ch);

	if (ch == '#') 
	{
		T = NULL;
		return 0;
	}
	else {
		T = (BiTNode*)malloc(sizeof(BiTNode));
		if (T == NULL) {
			printf("内存分配失败\n");
			exit(0);
		}
		T->data = ch; // 根节点赋值
		CreateBiTree(T->LChild); // 递归创建左子树
		CreateBiTree(T->RChild); // 递归创建右子树
		return 1;
	}
}

int Isempty(BiTree& T) {
	if (T == NULL)
		return 1; // 二叉树为空,返回1
	else
		return 0; // 不为空返回0;
}

void DLR(BiTree& T) {
	if (Isempty(T)) {
		return;
	}
	printf("%c", T->data);
	DLR(T->LChild); // 递归左子树
	DLR(T->RChild); // 递归右子树
}

void LDR(BiTree& T) {
	if (Isempty(T)) {
		return;
	}
	LDR(T->LChild); // 递归左子树
	printf("%c", T->data);
	LDR(T->RChild); // 递归右子树
}

void LRD(BiTree& T) {
	if (Isempty(T)) {
		return;
	}
	LRD(T->LChild); // 递归左子树
	LRD(T->RChild); // 递归右子树
	printf("%c", T->data);
}

//计算二叉树节点个数的函数
int CountNodes(BiTree T) //递归嵌套调用
{
	if (T == NULL) {
		return 0; // 空树,节点个数为0
	}
	else {
		return 1 + CountNodes(T->LChild) + CountNodes(T->RChild); // 节点个数等于根节点加上左子树节点个数和右子树节点个数的和
	}
}

void ClearBiTree(BiTree& T)//清空
{
	if (Isempty(T))
		return;

		ClearBiTree(T->LChild);//清空左孩子
		ClearBiTree(T->RChild);//清空右孩子
		free(T);//释放T
		T = NULL;//将T指向空
}

int BiTreeleaf(BiTree& T)//计算叶子个数
{
	if (T == NULL)//根节点为空 返回0
		return 0;
	if (T->LChild == NULL && T->RChild == NULL)//左右节点为空返回1 
		return 1;
	return BiTreeleaf(T->LChild) + BiTreeleaf(T->RChild);//递归调用
}

int BiTreeHight(BiTree& T)//计算树的深度
{
	if (T == NULL)
		return 0;
	int Lhight = BiTreeHight(T->LChild);
	int Rhight = BiTreeHight(T->RChild);
	return Lhight > Rhight ? Lhight + 1: Rhight + 1;
}

void Getnode(BiTree& T,char target,BiTNode**result)//查找节点返回位置
{
	if (T == NULL)
	{
		*result = NULL;
		return;
	}
	if (T->data == target)
	{
		*result = T;
		return;
	}
	Getnode(T->LChild, target, result);
	if (*result != NULL)
		return;
	Getnode(T->RChild, target,result);
}

int OperateMenu() {
	int code;
	printf("=========================================================\n");
	printf("请选择操作:\n");
	printf("0. 退出\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("9. 查找节点返回位置\n");
	printf("=========================================================\n");
	printf("请输入操作代码:");
	scanf("%d", &code);
	return code;
}

int main() {
	BiTree T = NULL; // 初始化二叉树为空
	printf("初始化成功\n");
	int code;
	do {
		code = OperateMenu(); // 显示操作菜单,并获取用户选择的操作代码
		switch (code) {
		case 0:
			printf("程序已退出。\n");
			exit(0);
		case 1:
			printf("请输入字符('#'为结束):\n");
			//fflush(stdin);
			//rewind(stdin);
			CreateBiTree(T);
			break;
		case 2:
			if (Isempty(T)) {
				printf("二叉树为空!\n");
				break;
			}
			else {
				printf("先序遍历结果为:");
				DLR(T); // 先序遍历
				printf("\n");
				break;
			}
		case 3:
			if (Isempty(T)) {
				printf("二叉树为空!\n");
				break;
			}
			else {
				printf("中序遍历结果为:");
				LDR(T); // 中序遍历
				printf("\n");
				break;
			}
		case 4:
			if (Isempty(T)) {
				printf("二叉树为空!\n");
				break;
			}
			else {
				printf("后序遍历结果为:");
				LRD(T); // 后序遍历
				printf("\n");
				break;
			}
		case 5:
			if (Isempty(T))
			{
				printf("二叉树为空\n");
			}
			else
			{
				printf("二叉树中节点个数为:\n");
				printf("%d", CountNodes(T));
				printf("\n");
			}
			break;
		case 6:
			if (Isempty(T))
				printf("二叉树为空,无法清空\n");
			else
			{ 
				ClearBiTree(T);
				printf("二叉树已清空\n");
			}
			break;
		case 7:
			if(Isempty(T))
				printf("二叉树为空,无法计算\n");
			else
			{
				int flag1 = BiTreeleaf(T);
				printf("该二叉树中的叶子个数为%d\n", flag1);
			}
			break;
		case 8:
			if (Isempty(T))
				printf("二叉树为空,无法计算\n");
			else
			{
				int flag2 = BiTreeHight(T);
				printf("该二叉树中的深度为%d\n", flag2);
			}
			break;
		case 9:
			if (Isempty(T))
				printf("二叉树为空,无法查找\n");
			else
			{
				BiTNode* result;
				char target;
				printf("请输入查找的节点元素\n");
				scanf("%c", &target);
				Getnode(T, target, &result);
				if (result != NULL)
					printf("该节点的位置为:%p(16进制)\n", result);
				else
					printf("未找到该节点\n");
				
			}
			break;
		default:
			printf("无效的操作代码,请重新输入。\n");
			break;
		}
	} while (code != 0); // 当操作代码为0时退出循环
	return 0;
}

编译软件为vs2022,代码中,为消除键盘缓冲区,应使用fflush(stdin),但由于vs2015之后不识别此函数,故替换为rewind(stdin)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北京最后的深情

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

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

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

打赏作者

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

抵扣说明:

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

余额充值