数据结构:二叉树构建及其运算的递归设计

typedef char ElementType;
#define MAX_SIZE 20
typedef struct BookTreeNode
{
ElementType data;
struct BookTreeNode* left;
struct BookTreeNode* right;
}BTNode;

括号表示法创建二叉树存储结构

我们想使用A(B,C(D,E))这样的方式创建一个树结构

  1. A:为树的根节点
  2. (:左括号,说明其具有左孩子,准备左插孩子
  3. ,:逗号吗,说明其具有右孩子,准备右插孩子
  4. ):右括号,说明其左右孩子均处理完毕,准备下一次插入孩子
void CreateBTree(BTNode*& bt, const char* arr)
{
bt = nullptr;
BTNode* St[MAX_SIZE]{ 0 }; //存储树结构的栈
BTNode* pRoot = nullptr;
int arr_index = 0;
int top = 0; //栈顶指针
int choice = 1; //choice=1:左插 choice=2:右插
char ch;
ch = arr[arr_index];
while (ch!='\0')
{
switch (ch)
{
case '(':
{
top++;
*(St+top) = pRoot;
choice = 1;
break;
}
case ')':
{
top--;
break;
}
case ',':
{
choice = 2;
break;
}
default:
{
pRoot = new BTNode;
pRoot->data = ch;
pRoot->left = pRoot->right = nullptr;
if (bt == nullptr)
{
//当树为空的时候,创建根节点
bt = pRoot;
}
else
{
//树不为空,根据k
switch (choice)
{
case 1:
St[top]->left = pRoot;
break;
default:
St[top]->right = pRoot;
break;
}
}
break;
}
}
arr_index++;
ch = arr[arr_index];
}
}

释放二叉树的空间

我们采用大问题转换为小问题的方式:

递归模型:

  1. 当树为空的时候:f(bt)=不做任何事情
  2. 树节点不为空:f(bt)=f(bt->left);f(bt)=f(bt->right);delete bt
void DestroyBTree(BTNode*& bt)
{
if (bt != nullptr)
{
DestroyBTree(bt->left);
DestroyBTree(bt->right);
delete bt;
}
}

求树的高度

两种方法: 个人感觉第一个比较好理解。

int BTHeight(BTNode*& bt)
{
#if 0
int leftHeight, rightHeight;
if (bt == nullptr)
{
//树为空
return 0;
}
else
{
leftHeight = BTHeight(bt->left); //求左子树高度
rightHeight = BTHeight(bt->right); //求右子树高度
return (leftHeight > rightHeight) ? (leftHeight + 1) : (rightHeight + 1);
}
#else
if (bt == nullptr)
{
return 0;
}
else
{
return max(BTHeight(bt->left), BTHeight(bt->right)) + 1;
}
#endif
}

求树的节点个数

int GetNodeCount(BTNode*& bt)
{
#if 0
int leftNumber, rightNumber;
if (bt == nullptr)
{
return 0;
}
else
{
leftNumber = GetNodeCount(bt->left);
rightNumber = GetNodeCount(bt->right);
return (leftNumber + rightNumber + 1);
}
return 0;
#else
if(bt == nullptr)
{
return 0;
}
else
{
return GetNodeCount(bt->left) + GetNodeCount(bt->right) + 1;
}
#endif
}

求树的所有叶子节点个数

int GetLitCount(BTNode*& bt)
{
int left, right;
if (bt == nullptr)
{ //bt为nullptr
return 0;
}
else if (bt->left==nullptr && bt->right==nullptr)
{ //bt为叶子节点
return 1;
}
else
{
left = GetLitCount(bt->left);//求左子树的叶子节点个数
right = GetLitCount(bt->right);//求右子树叶子节点的个数
return (left + right); //返回和
}
}

括号表示法输出树结构

使用的是根左右的前序遍历方式

void Display(BTNode*& bt)
{
if (bt != nullptr)
{
cout.put(bt->data);
if (bt->left != nullptr || bt->right != nullptr)
{
cout.put('(');
Display(bt->left);
if (bt->right != nullptr)
{
cout.put(',');
}
Display(bt->right);
cout.put(')');
}
}
}

完整测试

#include "MyTree.h"
int main()
{
BTNode* tree;
CreateBTree(tree, "A(B(D,E(G,H)),C)");
cout << GetLitCount(tree) << endl;
cout << GetNodeCount(tree) << endl;
cout << BTHeight(tree) << endl;
Display(tree);
DestroyBTree(tree):
return 0;
}

在这里插入图片描述

posted @   hugeYlh  阅读(66)  评论(0编辑  收藏  举报  
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示