博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS递归与二叉树的遍历
阅读量:5948 次
发布时间:2019-06-19

本文共 2108 字,大约阅读时间需要 7 分钟。

貌似大部分语言中的递归都差不多, 之所以在标题加JS是因为搜了下后感觉网上用js来描述这概念的不多, 简单地说递归就是函数调用自己的过程。下面的栗子可以很直观地展示递归的执行过程:

function rec(x){if(x!==1){   console.log(x)    rec(x-1)   console.log(x)    }   }rec(5) //输出为5 4 3 2 2 3 4 5

由这个栗子?可知:在递归调用语句前的语句执行是正常顺序, 但是递归调用语句后的执行却是相反的也就是说在递归还没有完成时,函数的输出结果暂时被挂起,因为一般在计算机中,是以栈的形式来实现递归,这个过程如下:

5 rec(4)     //第一级5 4 rec(3)   //第二级5 4 3 rec(2)  //第三级5 4 3 2 rec(1)  //第四级console.log() 2 3 4 5  //以出栈形式输出结果

当递归完成时, 执行流开始处理上一级递归中的递归语句后面的语句, 在这里是输出当前变量console.log(x)

递归非常适用于相同函数不同参数的迭代循环。但是因为需要为每一级的递归开辟内存所以递归的开销相对来说蛮大的, 在很多编程的语言中,对于递归的开销问题有个TCO优化(Tail Call Optimization)戳这篇博客了解更多?

之所以想起码这篇博客,是因为最近看《算法与数据结构JavaScript描述》(请拉黑此书,bug极多,极不推荐)中使用递归遍历二叉树的算法挺绕的, 写篇博客厘清下。

这里直接借用原书的代码(有删改), 以二叉树的的中序遍历为例:

// 节点对象的构造函数function Node(data, left, right) {   this.data = data;   this.left = left;   this.right = right;   this.show = show;}function show() {   return this.data;}//二叉树的构造函数function BST() {   this.root = null;   this.insert = insert;   this.inOrder = inOrder;   }//插入方法function insert(data) {   var n = new Node(data, null, null);   if (this.root == null) {      this.root = n;   }   else {      var current = this.root;      var parent;      while (true) {         parent = current;         if (data < current.data) {            current = current.left;            if (current == null) {               parent.left = n;               break;            }         }         else {            current = current.right;            if (current == null) {               parent.right = n;               break;            }         }      }   }}//调用两次递归遍历二叉树function inOrder(node) {   if (!(node == null)) {      inOrder(node.left);      console.log(node.show() )      inOrder(node.right);   }}//将以下数据导入二叉树nums.insert(23)nums.insert(45)nums.insert(16)nums.insert(37)nums.insert(3)nums.insert(99)nums.insert(22)  //中序遍历二叉树inOrder(nums.root)   /*输出结果为: 3 16 22 23 37 45 99*/

在inOrder函数中使用了两次递归,它的执行顺序是:沿左边找到最小值3,第一次递归完成, 之前被挂起的语句开始以出栈的形式执行,输出无子节点的节点3,然后回到上一级递归,输出其上一级递归中的节点16, 在节点16处, 存在子节点,于是执行向右递归,执行到无子节点的22,输出22后返回到节点16 , 执行流继续往回执行, 执行到根节点23,输出23后又插入一次向右递归,右递归到45, 存在左子节点,执行向左递归, 以此类推,就完成了这棵二叉树的中序遍历

附张遍历顺序示意图:

traversal order sketch

转载地址:http://nwdxx.baihongyu.com/

你可能感兴趣的文章
Tomcat访问日志详细配置
查看>>
get请求传递中文参数乱码解决方法
查看>>
苦战 自由软件的今生前世
查看>>
搭建 Discuz 论坛
查看>>
Go语言的国际化支持(资源文件翻译)
查看>>
install oracle 11g on linux (centos6) 遇到的问题
查看>>
PhoneGap插件开发流程
查看>>
iOS设计模式——桥接模式
查看>>
gitlab runner 优化
查看>>
快速添加百度网盘文件到Aria2 猴油脚本
查看>>
mac 无法登录mysql的解决办法
查看>>
Shiro权限判断异常之命名导致的subject.isPermitted 异常
查看>>
Hello world travels in cpp - 字符串(2)
查看>>
springMVC笔记系列(10)——CookieValue注解
查看>>
Spring框架笔记(六)——Spring IOC容器Bean之间的继承与依赖关系
查看>>
struts2自定义拦截器
查看>>
Eclipse安装adt插件后之后看不到andorid manger
查看>>
Kafka服务端脚本详解(1)一topics
查看>>
Zookeeper 集群安装配置,超详细,速度收藏!
查看>>
js中var self=this的解释
查看>>