二叉树相关题目

本文总结了二叉树的各种操作,包括求深度、节点数、叶子数等,并介绍了如何通过前序和中序遍历重建二叉树。还探讨了二叉树的遍历方法、判断平衡性和结构相似性等问题。

1、求二叉树深度

int GetDepth(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL) // 递归出口
  return 0;
 int depthLeft = GetDepth(pRoot->m_pLeft);
 int depthRight = GetDepth(pRoot->m_pRight);
 return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1); 
}

2、求二叉树总节点数

int GetNodeNum(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL) // 递归出口
  return 0;
 return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1;
}

3、求二叉树叶子数

int GetLeafNodeNum(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL)
  return 0;
 if(pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL)
  return 1;
 int numLeft = GetLeafNodeNum(pRoot->m_pLeft); // 左子树中叶节点的个数
 int numRight = GetLeafNodeNum(pRoot->m_pRight); // 右子树中叶节点的个数
 return (numLeft + numRight);
}

4、求k层节点个数

int GetNodeNumKthLevel(BinaryTreeNode * pRoot, int k)
{
 if(pRoot == NULL || k < 1)
  return 0;
 if(k == 1)
  return 1;
 int numLeft = GetNodeNumKthLevel(pRoot->m_pLeft, k-1); // 左子树中k-1层的节点个数
 int numRight = GetNodeNumKthLevel(pRoot->m_pRight, k-1); // 右子树中k-1层的节点个数
 return (numLeft + numRight);
}

5、二叉树遍历(前序遍历)

void PreOrderTraverse(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL)
  return;
 Visit(pRoot); // 访问根节点
 PreOrderTraverse(pRoot->m_pLeft); // 前序遍历左子树
 PreOrderTraverse(pRoot->m_pRight); // 前序遍历右子树
}

6、分层遍历

void LevelTraverse(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL)
  return;
 queue<BinaryTreeNode *> q;
 q.push(pRoot);
 while(!q.empty())
 {
  BinaryTreeNode * pNode = q.front();
  q.pop();
  Visit(pNode); // 访问节点
  if(pNode->m_pLeft != NULL)
   q.push(pNode->m_pLeft);
  if(pNode->m_pRight != NULL)
   q.push(pNode->m_pRight);
 }
 return;
}

7、求二叉树镜像

BinaryTreeNode * Mirror(BinaryTreeNode * pRoot)
{
 if(pRoot == NULL) // 返回NULL
  return NULL;
 BinaryTreeNode * pLeft = Mirror(pRoot->m_pLeft); // 求左子树镜像
 BinaryTreeNode * pRight = Mirror(pRoot->m_pRight); // 求右子树镜像
 // 交换左子树和右子树
 pRoot->m_pLeft = pRight;
 pRoot->m_pRight = pLeft;
 return pRoot;
}

8、判断两棵二叉树结构是否相同

bool StructureCmp(BinaryTreeNode * pRoot1, BinaryTreeNode * pRoot2)
{
 if(pRoot1 == NULL && pRoot2 == NULL) // 都为空,返回真
  return true;
 else if(pRoot1 == NULL || pRoot2 == NULL) // 有一个为空,一个不为空,返回假
  return false;
 bool resultLeft = StructureCmp(pRoot1->m_pLeft, pRoot2->m_pLeft); // 比较对应左子树 
 bool resultRight = StructureCmp(pRoot1->m_pRight, pRoot2->m_pRight); // 比较对应右子树
 return (resultLeft && resultRight);
}

9、判断二叉树是不是平衡二叉树

bool IsAVL(BinaryTreeNode * pRoot, int & height)
{
 if(pRoot == NULL) // 空树,返回真
 {
  height = 0;
  return true;
 }
 int heightLeft;
 bool resultLeft = IsAVL(pRoot->m_pLeft, heightLeft);
 int heightRight;
 bool resultRight = IsAVL(pRoot->m_pRight, heightRight);
 if(resultLeft && resultRight && abs(heightLeft - heightRight) <= 1) // 左子树和右子树都是AVL,并且高度相差不大于1,返回真
 {
  height = max(heightLeft, heightRight) + 1;
  return true;
 }
 else
 {
  height = max(heightLeft, heightRight) + 1;
  return false;
 }
}

10、由前序遍历序列和中序遍历序列重建二叉树

BinaryTreeNode * RebuildBinaryTree(int* pPreOrder, int* pInOrder, int nodeNum)
{
 if(pPreOrder == NULL || pInOrder == NULL || nodeNum <= 0)
  return NULL;
 BinaryTreeNode * pRoot = new BinaryTreeNode;
 // 前序遍历的第一个数据就是根节点数据
 pRoot->m_nValue = pPreOrder[0];
 pRoot->m_pLeft = NULL;
 pRoot->m_pRight = NULL;
 // 查找根节点在中序遍历中的位置,中序遍历中,根节点左边为左子树,右边为右子树
 int rootPositionInOrder = -1;
 for(int i = 0; i < nodeNum; i++)
  if(pInOrder[i] == pRoot->m_nValue)
  {
   rootPositionInOrder = i;
   break;
  }
 if(rootPositionInOrder == -1)
 {
  throw std::exception("Invalid input.");
 }
 // 重建左子树
 int nodeNumLeft = rootPositionInOrder;
 int * pPreOrderLeft = pPreOrder + 1;
 int * pInOrderLeft = pInOrder;
 pRoot->m_pLeft = RebuildBinaryTree(pPreOrderLeft, pInOrderLeft, nodeNumLeft);
 // 重建右子树
 int nodeNumRight = nodeNum - nodeNumLeft - 1;
 int * pPreOrderRight = pPreOrder + 1 + nodeNumLeft;
 int * pInOrderRight = pInOrder + nodeNumLeft + 1;
 pRoot->m_pRight = RebuildBinaryTree(pPreOrderRight, pInOrderRight, nodeNumRight);
 return pRoot;
}

转载于:https://my.oschina.net/u/2350638/blog/499800

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值