二叉树广度遍历java,深度优先遍历相当于二叉树

  二叉树广度遍历java,深度优先遍历相当于二叉树

  如何解决写爬虫IP受阻的问题?立即使用。

  这两天在做二叉树相关的算法题,做一些学习笔记。(连二叉树都没有?我真的不熟练,平时也不用写二叉树相关的算法或者数据结构。因为自己做饭,所以要更加努力学习!)

  定义

  先看看维基百科的解释:在计算机科学中,二叉树(英文:Binary tree)是每个节点最多有两个分支的树结构(即不存在分支大于2的节点)。通常,分支被称为“左子树”或“右子树”。二叉树的分支有左右顺序,不能随意颠倒。

  由于二叉树定义的特点,它具有高度的局部可重复性,所以在首先对二叉树进行深度遍历时,通常采用递归的方式实现。这样实现的代码非常简洁,美观,易于理解。

  深度优先遍历

  一般来说,我们的深度优先遍历二叉树有三种最常见的顺序遍历:前序、中序和后序。

  遍历的顺序是:访问根节点——遍历左子树——遍历右子树。

  中间顺序的遍历顺序是:遍历左子树-访问根节点-遍历右子树。

  下面的遍历顺序是:遍历左子树-遍历右子树-访问根节点。

  注意,这里的左右是整个子树,不是一个节点。因为我们需要遍历整个树,所以每次遍历都是按照这个顺序执行的,直到叶子节点。

  例如,假设有以下二叉树:

  通过前序遍历得到的序列是A-B-C-D-E

  遍历中间顺序得到的序列是B-A-D-C-E

  后序遍历得到的序列是B-D-E-C-A

  先说前序遍历方面的思维方式(不建议去人肉递归,至少我的大脑承受不了三层。):

  递归的第一级:

  先访问根节点,所以输出根节点A,然后遍历左子树(L1),再遍历右子树(R1);

  二级递归:

  对于L1,先访问根节点,所以输出此时的根节点B,然后发现B的左右子树为空,结束递归;

  对于R1,先访问根节点,所以输出此时的根节点C,然后遍历左子树(L2),再遍历右子树(R2);

  第三层递归:

  对于L2,先访问根节点,所以输出此时的根节点D,然后发现D的左右子树为空,结束递归;

  对于R2,先访问根节点,所以输出此时的根节点E,然后发现E的左右子树都是空的,结束递归;

  前中后序特征

  根据前中后的定义,其实我们很容易发现以下几个特点:

  顺序中的第一个必须是根节点,顺序中的最后一个必须是根节点。

  每种排序的左子树和右子树的分布是有规律的。

  每个子树都遵循上述两条规则的树。

  这些特征是定义中秩序的表现。

  各种推导

  下面是二叉树遍历的一些基本算法:

  给定一棵二叉树,求其前/中/后序遍历的序列;

  根据前序和中序导出后序(或整个二叉树);

  根据后序和中序导出前序(或整个二叉树);

  如前所述,二叉树的遍历通常是通过递归完成的。对于递归,有一些模板可以直接应用:

  public void recurve(int level,int param) {

  //终止符

  if (level MAX_LEVEL) {

  //处理结果

  返回;

  }

  //处理当前逻辑

  过程(级别,参数);

  //深入查看

  recurve(level 1,new param);

  //恢复当前状态

  }这是超哥(覃超)这两天在极客时间的算法训练营里讲的一个实用技巧(这个模板特别适合新手)。按照上面的三个步骤(如果有局部变量需要释放或者额外处理,做第四步)以更有条理的方式编写递归代码。

  这里以前面订单和中间订单推导后面订单为例:

  首先初始化两个序列:

  int[]pressequence={ 1,2,3,4,5,6,7,8,9 };

  int[] inSequence={2,3,1,6,7,8,5,9,4 };通过上面提到的特征,我们已经可以找到最小重复子问题,每次递归。

  根据前导码的第一个结点值,匹配前导码中节点值所在的索引I,这样我们就可以得到索引I中分别对应左右两个子树的两部分,然后分别遍历这左右两个子树,再输出当前前导码的第一个节点值,也就是根节点。

  按照自顶向下的编程方法,我们可以先编写下面的初始递归调用:

  list integer result=new ArrayList();

  preandtopost(0,0,preSequence.length,preSequence,inSequence,result);第一个参数指示前导序列的第一个元素的索引;

  第二个参数指示中间顺序序列的第一个元素索引;

  第三个参数表示序列的长度;

  第四个参数表示前导序列;

  第五个参数表示后续序列;

  第六个参数用于保存结果;

  我们先考虑终止条件是什么,也就是递归什么时候结束,当我们的根节点为空的时候就结束,也就是序列长度为零的时候。

  if(长度==0) {

  返回;

  }然后考虑处理逻辑,也就是找到索引I:

  int I=0;

  while (inSequence[inIndex i]!=preSequence[preIndex]) {

  我;

  }然后开始向下递归:

  preandtopost(pre index 1,inIndex,I,preSequence,inSequence,result);

  preandtopost(pre index I 1,inIndex i 1,length - i - 1,preSequence,inSequence,result);

  result . add(pre sequence[pre index]);因为推导顺序,所以顺序如上,添加根节点的操作在最后。怎么得到前三个参数?我们可以通过第一次遍历得到它们。

  前序序列中第一个节点1的索引在中序序列中是2。此时此刻

  左子树中序序列的起始索引是全序列的第一个索引,长度为2;

  左子树的前序序列的初始索引是总序列的第二个索引,长度为2;

  右子树的中序序列的起始索引是总序列的第三个索引,其长度为length-3;

  右子树的前序序列的起始索引为总序列的第三个索引,长度为length-3;

  完整的代码如下:

  /**

  *根据前面序列和中间序列推导后面序列。

  *

  * @param preIndex前导索引

  * @param inIndex中间顺序索引

  * @param length序列长度

  * @ param preSequence前导序列

  * @param inSequence中间序列

  * @param结果结果序列

  */

  private void preAndInToPost(int preIndex,int inIndex,int length,int[] preSequence,int[] inSequence,ListInteger result) {

  if(长度==0) {

  返回;

  }

  int I=0;

  while (inSequence[inIndex i]!=preSequence[preIndex]) {

  我;

  }

  preandtopost(pre index 1,inIndex,I,preSequence,inSequence,result);

  preandtopost(pre index I 1,inIndex i 1,length - i - 1,preSequence,inSequence,result);

  result . add(pre sequence[pre index]);

  }推荐教程:以上《java教程》是java中二叉树深度优先遍历的详细内容。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: