共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)。