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

手机制作公章的软件狼雨seo培训

手机制作公章的软件,狼雨seo培训,上海网站优化案例,北京汽车网站建设一文搞定面试中的二叉树问题 版权所有#xff0c;转载请注明出处#xff0c;谢谢#xff01; http://blog.csdn.net/walkinginthewind/article/details/7518888 树是一种比较重要的数据结构#xff0c;尤其是二叉树。二叉树是一种特殊的树#xff0c;在二叉树中每个节点…一文搞定面试中的二叉树问题 版权所有转载请注明出处谢谢 http://blog.csdn.net/walkinginthewind/article/details/7518888 树是一种比较重要的数据结构尤其是二叉树。二叉树是一种特殊的树在二叉树中每个节点最多有两个子节点一般称为左子节点和右子节点或左孩子和右孩子并且二叉树的子树有左右之分其次序不能任意颠倒。二叉树是递归定义的因此与二叉树有关的题目基本都可以用递归思想解决当然有些题目非递归解法也应该掌握如非递归遍历节点等等。本文努力对二叉树相关题目做一个较全的整理总结希望对找工作的同学有所帮助。 二叉树节点定义如下 struct BinaryTreeNode {     int m_nValue;     BinaryTreeNode* m_pLeft;     BinaryTreeNode* m_pRight; }; 相关链接 轻松搞定面试中的链表题目 题目列表 1. 求二叉树中的节点个数 2. 求二叉树的深度 3. 前序遍历中序遍历后序遍历 4.分层遍历二叉树按层次从上往下从左往右 5. 将二叉查找树变为有序的双向链表 6. 求二叉树第K层的节点个数 7. 求二叉树中叶子节点的个数 8. 判断两棵二叉树是否结构相同 9. 判断二叉树是不是平衡二叉树 10. 求二叉树的镜像 11. 求二叉树中两个节点的最低公共祖先节点 12. 求二叉树中节点的最大距离 13. 由前序遍历序列和中序遍历序列重建二叉树 14.判断二叉树是不是完全二叉树 详细解答 1. 求二叉树中的节点个数 递归解法 1如果二叉树为空节点个数为0 2如果二叉树不为空二叉树节点个数 左子树节点个数 右子树节点个数 1 参考代码如下 [cpp] view plaincopy int GetNodeNum(BinaryTreeNode * pRoot)   {       if(pRoot  NULL) // 递归出口           return 0;       return GetNodeNum(pRoot-m_pLeft)  GetNodeNum(pRoot-m_pRight)  1;   }   2. 求二叉树的深度递归解法1如果二叉树为空二叉树的深度为02如果二叉树不为空二叉树的深度 max(左子树深度 右子树深度) 1参考代码如下[cpp] view plaincopy 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);    }   3. 前序遍历中序遍历后序遍历前序遍历递归解法1如果二叉树为空空操作2如果二叉树不为空访问根节点前序遍历左子树前序遍历右子树参考代码如下[cpp] view plaincopy void PreOrderTraverse(BinaryTreeNode * pRoot)   {       if(pRoot  NULL)           return;       Visit(pRoot); // 访问根节点       PreOrderTraverse(pRoot-m_pLeft); // 前序遍历左子树       PreOrderTraverse(pRoot-m_pRight); // 前序遍历右子树   }   中序遍历递归解法1如果二叉树为空空操作。2如果二叉树不为空中序遍历左子树访问根节点中序遍历右子树参考代码如下[cpp] view plaincopy void InOrderTraverse(BinaryTreeNode * pRoot)   {       if(pRoot  NULL)           return;       InOrderTraverse(pRoot-m_pLeft); // 中序遍历左子树       Visit(pRoot); // 访问根节点       InOrderTraverse(pRoot-m_pRight); // 中序遍历右子树   }   后序遍历递归解法1如果二叉树为空空操作2如果二叉树不为空后序遍历左子树后序遍历右子树访问根节点参考代码如下[cpp] view plaincopy void PostOrderTraverse(BinaryTreeNode * pRoot)   {       if(pRoot  NULL)           return;       PostOrderTraverse(pRoot-m_pLeft); // 后序遍历左子树       PostOrderTraverse(pRoot-m_pRight); // 后序遍历右子树       Visit(pRoot); // 访问根节点   }   4.分层遍历二叉树按层次从上往下从左往右 相当于广度优先搜索使用队列实现。队列初始化将根节点压入队列。当队列不为空进行如下操作弹出一个节点访问若左子节点或右子节点不为空将其压入队列。 [cpp] view plaincopy void LevelTraverse(BinaryTreeNode * pRoot)   {       if(pRoot  NULL)           return;       queueBinaryTreeNode * 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;   }   5. 将二叉查找树变为有序的双向链表 要求不能创建新节点只调整指针。递归解法1如果二叉树查找树为空不需要转换对应双向链表的第一个节点是NULL最后一个节点是NULL2如果二叉查找树不为空如果左子树为空对应双向有序链表的第一个节点是根节点左边不需要其他操作如果左子树不为空转换左子树二叉查找树对应双向有序链表的第一个节点就是左子树转换后双向有序链表的第一个节点同时将根节点和左子树转换后的双向有序链表的最后一个节点连接如果右子树为空对应双向有序链表的最后一个节点是根节点右边不需要其他操作如果右子树不为空对应双向有序链表的最后一个节点就是右子树转换后双向有序链表的最后一个节点同时将根节点和右子树转换后的双向有序链表的第一个节点连接。参考代码如下[cpp] view plaincopy /******************************************************************************  参数  pRoot: 二叉查找树根节点指针  pFirstNode: 转换后双向有序链表的第一个节点指针  pLastNode: 转换后双向有序链表的最后一个节点指针  ******************************************************************************/   void Convert(BinaryTreeNode * pRoot,                 BinaryTreeNode *  pFirstNode, BinaryTreeNode *  pLastNode)   {       BinaryTreeNode *pFirstLeft, *pLastLeft, * pFirstRight, *pLastRight;       if(pRoot  NULL)        {           pFirstNode  NULL;           pLastNode  NULL;           return;       }          if(pRoot-m_pLeft  NULL)       {           // 如果左子树为空对应双向有序链表的第一个节点是根节点           pFirstNode  pRoot;       }       else       {           Convert(pRoot-m_pLeft, pFirstLeft, pLastLeft);           // 二叉查找树对应双向有序链表的第一个节点就是左子树转换后双向有序链表的第一个节点           pFirstNode  pFirstLeft;           // 将根节点和左子树转换后的双向有序链表的最后一个节点连接           pRoot-m_pLeft  pLastLeft;           pLastLeft-m_pRight  pRoot;       }          if(pRoot-m_pRight  NULL)       {           // 对应双向有序链表的最后一个节点是根节点           pLastNode  pRoot;       }       else       {           Convert(pRoot-m_pRight, pFirstRight, pLastRight);           // 对应双向有序链表的最后一个节点就是右子树转换后双向有序链表的最后一个节点           pLastNode  pLastRight;           // 将根节点和右子树转换后的双向有序链表的第一个节点连接           pRoot-m_pRight  pFirstRight;           pFirstRight-m_pLeft  pRoot;       }          return;   }   6. 求二叉树第K层的节点个数递归解法1如果二叉树为空或者k1返回02如果二叉树不为空并且k1返回13如果二叉树不为空且k1返回左子树中k-1层的节点个数与右子树k-1层节点个数之和参考代码如下[cpp] view plaincopy 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);   }   7. 求二叉树中叶子节点的个数完全二叉树有2*n-1 个节点,则它的叶子节点数为? 完全二叉树的节点数是奇数,说明此完全二叉树也是满二叉树,也就是说每个内部节点正好都有2个叶结点. 设内部节点数为a,叶节点数为b,结点总数为m,明显有abm (1) 非空满二叉树中所有节点的出度正好等于入度,每个内部节点出度为2,叶节点出度为0,所有节点的出度和为2a根节点入度为0,其他节点的入度为1,所有节点的入度和为ab-1;因此有2aab-1 (2) 由(1),(2)得 b(m1)/2,a(m-1)/2,ba1 也就是说,非空满二叉树的叶节点数正好比内部节点数多1 此完全二叉树的结点总数为2n-1,因此其叶结点数为n. 递归解法 1如果二叉树为空返回02如果二叉树不为空且左右子树为空返回13如果二叉树不为空且左右子树不同时为空返回左子树中叶子节点个数加上右子树中叶子节点个数参考代码如下[cpp] view plaincopy 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);   }   8. 判断两棵二叉树是否结构相同 不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。递归解法1如果两棵二叉树都为空返回真2如果两棵二叉树一棵为空另一棵不为空返回假3如果两棵二叉树都不为空如果对应的左子树和右子树都同构返回真其他返回假参考代码如下[cpp] view plaincopy 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. 判断二叉树是不是平衡二叉树递归解法1如果二叉树为空返回真2如果二叉树不为空如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1返回真其他返回假参考代码[cpp] view plaincopy 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. 求二叉树的镜像 递归解法1如果二叉树为空返回空2如果二叉树不为空求左子树和右子树的镜像然后交换左子树和右子树参考代码如下[cpp] view plaincopy 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;   }   11. 求二叉树中两个节点的最低公共祖先节点递归解法1如果两个节点分别在根节点的左子树和右子树则返回根节点2如果两个节点都在左子树则递归处理左子树如果两个节点都在右子树则递归处理右子树参考代码如下[cpp] view plaincopy bool FindNode(BinaryTreeNode * pRoot, BinaryTreeNode * pNode)   {       if(pRoot  NULL || pNode  NULL)           return false;          if(pRoot  pNode)           return true;          bool found  FindNode(pRoot-m_pLeft, pNode);       if(!found)           found  FindNode(pRoot-m_pRight, pNode);          return found;   }      BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot,                                         BinaryTreeNode * pNode1,                                         BinaryTreeNode * pNode2)   {       if(FindNode(pRoot-m_pLeft, pNode1))       {           if(FindNode(pRoot-m_pRight, pNode2))               return pRoot;           else               return GetLastCommonParent(pRoot-m_pLeft, pNode1, pNode2);       }       else       {           if(FindNode(pRoot-m_pLeft, pNode2))               return pRoot;           else               return GetLastCommonParent(pRoot-m_pRight, pNode1, pNode2);       }   }   递归解法效率很低有很多重复的遍历下面看一下非递归解法。非递归解法先求从根节点到两个节点的路径然后再比较对应路径的节点就行最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点参考代码如下[cpp] view plaincopy bool GetNodePath(BinaryTreeNode * pRoot, BinaryTreeNode * pNode,                     listBinaryTreeNode *  path)   {       if(pRoot  pNode)       {              path.push_back(pRoot);           return true;       }       if(pRoot  NULL)           return false;       path.push_back(pRoot);       bool found  false;       found  GetNodePath(pRoot-m_pLeft, pNode, path);       if(!found)           found  GetNodePath(pRoot-m_pRight, pNode, path);       if(!found)           path.pop_back();       return found;   }   BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot, BinaryTreeNode * pNode1, BinaryTreeNode * pNode2)   {       if(pRoot  NULL || pNode1  NULL || pNode2  NULL)           return NULL;       listBinaryTreeNode* path1;       bool bResult1  GetNodePath(pRoot, pNode1, path1);       listBinaryTreeNode* path2;       bool bResult2  GetNodePath(pRoot, pNode2, path2);       if(!bResult1 || !bResult2)            return NULL;       BinaryTreeNode * pLast  NULL;       listBinaryTreeNode*::const_iterator iter1  path1.begin();       listBinaryTreeNode*::const_iterator iter2  path2.begin();       while(iter1 ! path1.end()  iter2 ! path2.end())       {           if(*iter1  *iter2)               pLast  *iter1;           else               break;           iter1;           iter2;       }       return pLast;   }   在上述算法的基础上稍加变化即可求二叉树中任意两个节点的距离了。12. 求二叉树中节点的最大距离 即二叉树中相距最远的两个节点之间的距离。递归解法1如果二叉树为空返回0同时记录左子树和右子树的深度都为02如果二叉树不为空最大距离要么是左子树中的最大距离要么是右子树中的最大距离要么是左子树节点中到根节点的最大距离右子树节点中到根节点的最大距离同时记录左子树和右子树节点中到根节点的最大距离。参考代码如下 [cpp] view plaincopy int GetMaxDistance(BinaryTreeNode * pRoot, int  maxLeft, int  maxRight)   {       // maxLeft, 左子树中的节点距离根节点的最远距离       // maxRight, 右子树中的节点距离根节点的最远距离       if(pRoot  NULL)       {           maxLeft  0;           maxRight  0;           return 0;       }       int maxLL, maxLR, maxRL, maxRR;       int maxDistLeft, maxDistRight;       if(pRoot-m_pLeft ! NULL)       {           maxDistLeft  GetMaxDistance(pRoot-m_pLeft, maxLL, maxLR);           maxLeft  max(maxLL, maxLR)  1;       }       else       {           maxDistLeft  0;           maxLeft  0;       }       if(pRoot-m_pRight ! NULL)       {           maxDistRight  GetMaxDistance(pRoot-m_pRight, maxRL, maxRR);           maxRight  max(maxRL, maxRR)  1;       }       else       {           maxDistRight  0;           maxRight  0;       }       return max(max(maxDistLeft, maxDistRight), maxLeftmaxRight);   }   13. 由前序遍历序列和中序遍历序列重建二叉树 二叉树前序遍历序列中第一个元素总是树的根节点的值。中序遍历序列中左子树的节点的值位于根节点的值的左边右子树的节点的值位于根节点的值的右边。递归解法1如果前序遍历为空或中序遍历为空或节点个数小于等于0返回NULL。2创建根节点。 前序遍历的第一个数据就是根节点的数据在中序遍历中找到根节点的位置可分别得知左子树和右子树的前序和中序遍 历序列重建左右子树。 题目描述 输入某二叉树的前序遍历和中序遍历的结果请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}则重建二叉树并输出它的后序遍历序列。 输入 输入可能包含多个测试样例对于每个测试案例 输入的第一行为一个整数n(1n1000)代表二叉树的节点个数。 输入的第二行包括n个整数(其中每个元素a的范围为(1a1000))代表二叉树的前序遍历序列。 输入的第三行包括n个整数(其中每个元素a的范围为(1a1000))代表二叉树的中序遍历序列。 输出 对应每个测试案例输出一行 如果题目中所给的前序和中序遍历序列能构成一棵二叉树则输出n个整数代表二叉树的后序遍历序列每个元素后面都有空格。 如果题目中所给的前序和中序遍历序列不能构成一棵二叉树则输出”No”。 样例输入 81 2 4 7 3 5 6 84 7 2 1 5 3 8 681 2 4 7 3 5 6 84 1 2 7 5 3 8 6 样例输出 7 4 2 5 8 6 3 1 No 采用递归的方式重构二叉树关键是要考虑到一些特殊情况比如只有根节点的二叉树、只有左子树或只有右子树的二叉树以及二叉树根节点为NULL、前序中序序列不匹配导致不能重构二叉树等。 AC代码如下一直在如何实现判断能否重构二叉树的地方徘徊在九度论坛里大致看了下借鉴了下各位前辈的思路定义一个全局bool变量用来跟踪判断能够重构 [cpp] view plaincopy #includestdio.h   #includestdlib.h      typedef int ElemType;   typedef struct BTNode    {       ElemType data;       struct BTNode *left;       struct BTNode *right;   }BTNode,*BTree;      bool CanReBuild;    //用来标示是否能够重构二叉树      /*  pre为前序遍历数组inv为中序遍历数组len为数组长度重构二叉树*ppTree  */   void RebuildBinaryTree(BTree *ppTree,int *pre,int *inv,int len)   {       if(p
http://www.zqtcl.cn/news/778921/

相关文章:

  • 小型网站建设需要多少钱网站发布内容是否过滤
  • 网站如何推广运营漳平网站编辑价格
  • 海洋优质的网站建设企业微信下载官方网站
  • 十大免费ae模板网站wordpress 远程设置
  • 青岛网站的优化云南抖音推广
  • 做中英文版的网站需要注意什么如何偷别人dedecms网站的模板
  • 免费微网站制作最近三天发生的重要新闻
  • 网站优化网络推广seo编程软件python
  • 建设部网站官网合同免费申请网站永久
  • 遵化建设局网站哈尔滨网站制作公司价格
  • 科技因子网站建设方案河南网站推广优化公司
  • 什么网站了解国家建设的行情如何建设自己的php网站
  • 大连市平台网站外包公司和劳务派遣
  • 广州建网站公司排名嵌入式软件开发工程师工作内容
  • 计算机软件网站建设免费asp网站源码
  • 网站建设介绍ppt镇江网站搜索引擎优化
  • 珠海自助建站软件泉州网站开发
  • ios个人开发者账号多少钱拼多多seo怎么优化
  • 五金网站建设信息产业部备案网站
  • 网站被百度惩罚放弃互联网平台宣传推广方案
  • 自己怎么做网站首页自动app优化
  • 图形设计网站泉州网站建设企业
  • 免费建各种网站有没有做网站的团队
  • 做网站做网站的公司电商网站怎么做
  • 福建专业网站建设公司《设计》韩国
  • 怎么区分网站是模板做的Wordpress福利资源模板
  • 文案类的网站最新域名网站
  • 网站seo优化效果智能营销系统开发
  • 国外做储物的网站个人网站建设在哪里
  • 北京高端网站设计外包公司不用代码做网站的工具