当前位置: 首页 > news >正文

二叉树的基本功能实现

一.二叉树的结构及实现

1.二叉树的结构

在之前的章节中已经介绍过,二叉树是一种特殊的树,其最大度为2,及最多有左,右两个孩子,结构图如下

在此之前已经讨论过一些特殊的二叉树,这里讨论一般的二叉树 

2.二叉树的实现

由以上结构我们用这样的代码来表示二叉树

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;//节点数据struct BinaryTreeNode* left;//左孩子struct BinaryTreeNode* right;//右孩子
}BTNode;

由于搜索二叉树红黑树等涉及到C++中STL模板的知识,这里直接手搓出一颗二叉树

//创建一个二叉树节点
BTNode* BuyNode(int x){BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");return NULL;}node->data = x;node->left = NULL;node->right = NULL;return node;
}BTNode* CreatBinaryTree()
{
//创建一系列二叉树节点BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(6);//通过节点内部指针手动调整为树的结构node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;node5->right = node7;return node1;
}

 根据以上创建二叉树的步骤,其结构如下:

之后定义的操作将基于此结构进行

二.二叉树的基本操作

1.前中后序遍历 

前中后序遍历均为二叉树深度遍历的方法,其区别在于遍历根的时机不同。如前序遍历的顺序为根,左子树,右子树,以此类推 

前序遍历

void PrevOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}printf("%d ", root->data);PrevOrder(root->left);PrevOrder(root->right);
}

 若考虑将空节点的值打印为N,上图的二叉树进行前序遍历的结果为:1 2 3 N N 4 5 N 6 6

这里的前序遍历利用了二叉树的递归定义,以及函数栈帧的创建与销毁。

这里仅展示部分函数栈帧的创建与销毁。需要注意的是,若第n层栈帧return时,并非直接return到main函数,而是返回到第n-1层调用该栈帧的栈帧。等PrevOrder函数所有栈帧均返回值后将函数的返回值返回main函数。

中序遍历

原理与前序遍历类似,不过需要修改根的遍历时机。

void InOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}

 后序遍历

void RearOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}RearOrder(root->left);RearOrder(root->right);printf("%d ", root->data);}

 2.求树的节点总数

在这里我们使用分治的思想(本质上还是递归)处理这个问题

int TreeSize(BTNode* root)
{return root == NULL ? 0 :TreeSize(root->left) + TreeSize(root->right) + 1;
}

当节点为空时返回0,将左子树与右子树的总结点相加再+1(根节点)即为树的节点总数

3.求叶子节点总数

int TreeLeafSize(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return TreeLeafSize(root->left)+ TreeLeafSize(root->right);
}

当是空树,返回0;当一个节点没有左右孩子时,即为叶子节点。依旧采用分治的思想,将左右子树的叶子节点加起来即为总叶子节点数

4.求树的高度

int TreeHeight(BTNode* root)
{if (root == NULL)return 0;int leftHeight = TreeHeight(root->left);int rightHeight = TreeHeight(root->right);return leftHeight > rightHeight ?leftHeight + 1 : rightHeight + 1;
}

依旧采用分治思想,一棵树的高度为左右子树中较高的那颗再+1

注意每层计算的高度最好将其返回存储(即这里的leftHeight和rightHeight),否则会存在时间效率问题

相关文章:

  • Sentinel源码—1.使用演示和简介一
  • linuxbash原理
  • docker 多主机容器组网
  • x-cmd install | jellex - 用 Python 语法在终端里玩转 JSON 数据!
  • 自然语言交互:NAS进化的下一站革命
  • 智能云图库-1-项目初始化
  • 医学成像中的对比语言-图像预训练模型(CLIP):一项综述|文献速递-深度学习医疗AI最新文献
  • Multisim使用教程详尽版--(2025最新版)
  • 数据库索引深度解析:原理、类型与高效使用实践
  • 图像处理有哪些核心技术?技术发展现状如何?
  • 【信息安全】黑芝麻A1000芯片安全启动方案
  • Android Studio 日志系统详解
  • [OS] vDSO + vvar(频繁调用的处理) | 存储:寄存器(高效)和栈(空间大)| ELF标准包装规范(加速程序加载)
  • springboot调用python文件,在ubuntu上部署,踩坑之旅(已部署成功)
  • Redis的Key的过期策略
  • 【笔试强训day19】
  • Spring 事件机制与观察者模式的深度解析
  • 《 C++ 点滴漫谈: 三十三 》当函数成为参数:解密 C++ 回调函数的全部姿势
  • vue2实现在屏幕中有一个小机器人可以随意移动
  • 数字化引擎再升级:小匠物联十周年庆典与全链路创新实践
  • 纽约大学朗格尼医学中心的转型带来哪些启示?
  • “上海之帆”巡展在日本大阪开幕,松江区组织企业集体出展
  • 国家主席习近平同普京总统签署关于进一步深化中俄新时代全面战略协作伙伴关系的联合声明
  • 调节负面情绪可以缓解慢性疼痛
  • 小米回应SU7Ultra排位模式限制车辆动力:暂停推送更新
  • 山东滕州市醉驾交通事故肇事人员已被刑拘