通过二叉树的遍历理解递归
来源:互联网 发布:显示淘宝下架插件 编辑:程序博客网 时间:2024/05/21 22:38
前言
对于递归自己一直处于迷迷糊糊的状态,看了超多和递归有关的资料,但还是不是特别理解,今天又看了一上午,觉得有些收获,打算写下了,加深理解。
前一段时间写的三种遍历的可视化,有兴趣的同学可以参考
demo地址:
http://crystalyy.github.io/resume/task/task22/index.html
代码地址:
https://github.com/crystalYY/resume/blob/gh-pages/task/task22/index.html
正文
说明:以JavaScript为程序的实现语言
以下二叉树是这篇博文的“主角”
重点介绍先序遍历
具体实现代码
function preorder(node){ if(!!node){//转换为布尔值 divlist.push(node); preorder(node.firstElementChild); preorder(node.lastElementChild); } }
对代码的几点说明
- divlist为一个数组,是一个全局变量,存储最终遍历结果
- 可能有的同学不熟悉JavaScript,
node.firstElementChild
与node.lastElementChild
分别指父节点的第一个元素节点和最后一个元素节点,即对应父节点的左孩子和右孩子。 - 二叉树是以DOM树的形式模拟
所谓递归可以分为两部分来理解:“递”和“归”。
“递”指按照代码执行顺序执行,这个和我们正常的思维一致不难理解。但有一点需要注意的是,在“递”的同时会把节点按照访问的顺序逐次压入到一个堆栈中。
“归”是指“递”进行到尽头时,开始根据“递”的过程中形成的堆栈进行出栈,最终得到结果。
对于二叉树的先序遍历,可以看出包含了两个对自己的调用,及包含两个遍历。
我们首先传进去的node是1,根据程序执行过程,我们可以知道在执行到一个阶段的尽头时,将会形成这样一个堆栈
由于左子树已经到了尽头,所以第一个遍历暂告一段落。按照代码执行的顺序,接下来需要执行preorder(node.lastElementChild);
也就是右子树的遍历,因为4依然没有右孩子,所以按照出栈的顺序依次遍历2和1的右子树。为了说明简单,再次贴一下代码
function preorder(node){ if(!!node){//转换为布尔值 divlist.push(node); preorder(node.firstElementChild); preorder(node.lastElementChild); } }
再来具体分析一下遍历2的右孩子时的过程。
当把2的节点传给preorder函数时,只执行了preorder(node.firstElementChild);
,preorder(node.lastElementChild);
还没有执行,按照程序执行顺序此时需要执行。
具体的执行步骤如下:
此时堆栈内又依次被压入了5,6,7三个元素节点
总结
递归也没有那么可怕,该执行的代码还是会执行,不过顺序可能和我们平常的思维不一致。它会不断的调用自身直到一个停止条件的满足,然后再回溯会第一个节点。
思维可能不清晰,如发现问题恳请指正,小女子不胜感谢~
- 通过二叉树的遍历理解递归
- [数据结构]对三序非递归遍历二叉树的理解
- 先序遍历二叉树的递归算法怎样理解
- 先序遍历二叉树的递归算法怎样理解
- 深入理解二叉树的非递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- 二叉树的递归遍历
- poj 2886-Who Gets the Most Candies?(线段树)
- ubuntu上安装vim编译器
- Android 中 Bitmap 和 Drawable
- Redis常用数据类型
- 剑指offer 44题 【抽象建模能力】扑克牌的顺序
- 通过二叉树的遍历理解递归
- javascript 图片转base64
- 【jzoj4668】【腐败】【数论】【快速乘】
- unity语言本地化插件 I2 Location2.5.6使用简单记录
- 【cf229D】Towers
- JNI - 加解密时错误的使用strlen和strncpy函数
- 对有数据的CUBE加IO
- 一句代码搞定 Android 底部弹框
- 帮助