JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】


Posted in Javascript onMay 07, 2018

本文实例讲述了JavaScript实现的DOM树遍历方法。分享给大家供大家参考,具体如下:

二叉 DOM 树的遍历

function Tree() {
   var Node = function(key){
      this.key = key;
      this.left = null;
      this.right = null;
   }
   root =null;
}

前序遍历

首先访问根结点,然后遍历左子树,最后遍历右子树

Tree.prototype.preOrderTraverse = function(callback){
  preOrder(root, callback);
}
var preOrder = function(node,callback){
  if(node !== null){
    callback(node.key);
    preOrder(node.left, callback);
    preOrder(node.right, callback);
  }
}

修改为DOM二叉树:

var preOrder = function(node,callback) {
  callback(node);
  if(node.firstElementChild) {//先判断子元素节点是否存在
     this.preOrder(node.firstElementChild,callback);
  }
  if(node.lastElementChild) {
    this.preOrder(node.lastElementChild,callback);
  }
};

中序遍历

首先遍历左子树,然后访问根结点,最后遍历右子树。

Tree.prototype.inOrderTraverse = function(callback){
  inOrder(root, callback);
}
var inOrder = function(node,callback){
  if(node !== null){
    inOrder(node.left,callback);
    callback(node.key);
    inOrder(node.right, calback);
  }
}

修改为DOM二叉树:

var inOrder = function(node,callback){
  if(node.firstElementChild) {
  this.inOrder(node.firstElementChild);
  }
  callback(node);
  if(node.lastElementChild) {
  this.inOrder(node.lastElementChild);
  }
}

后序遍历

首先遍历左子树,然后遍历右子树,最后访问根结点。

Tree.prototype.postOrderTraverse = function(callback){
  postOrder(root, callback);
}
var postOrder = function(node,callback){
  if(node !== null){
    postOrder(node.left,callback);
    postOrder(node.right, calback);
    callback(node.key);
  }
}

修改为DOM二叉树:

var postOrder = function(node,callback){
  if(node.firstElementChild) {
  this.postOrder(node.firstElementChild);
  }
  if(node.lastElementChild) {
  this.postOrder(node.lastElementChild);
  }
  callback(node);
}

多叉 DOM 树的遍历

广度优先遍历

首先遍历根节点,然后访问第一层节点,第二层节点,....,直到访问到最后一层。

借助于队列,用非递归的方式对多叉树进行遍历

Tree.prototype.BFSearch = function(node,callback){
  var queue=[];
  while(node!=null){
      callback(node);
    if(node.children.length!=0){
    for (var i=0;i<node.children.length;i++){
      queue.push(node.children[i]);//借助于队列,暂存当前节点的所有子节点
    }
    }
      node=queue.shift();//先入先出,借助于数据结构:队列
  }
};

深度优先遍历

首先遍历根节点,然后沿着一条路径遍历到最深的一层,最后在逐层返回。

借助于栈,实现多叉 DOM树 的深度优先遍历。

Tree.prototype.DFSearch = function(node,callback){
    var stack=[];
    while(node!=null){
    callback(node);
    if(node.children.length!=0){
    for (var i=node.children.length-1;i>=0;i--){//按照相反的子节点顺序压入栈
      stack.push(node.children[i]);//将该节点的所有子节点压入栈
    }
    }
      node = stack.pop();//弹出栈的子节点顺序就是原来的正确顺序(因为栈是先入后出的)
  }
};

二叉 DOM 树的前序、中序、后序遍历,是深度优先遍历的特例

因此,参考深度优先遍历,借助栈,可以以非递归的方式,实现二叉 DOM 树的  前序、中序和后序遍历

非递归实现二叉 DOM 树的前序遍历

Tree.prototype.preOrder = function(node,callback) {
    var stack=[];
    while(node!== null || stack.length!=0){
      while(node!==null){
        stack.push(node);
        callback.push(node);
        node=node.firstElementChild;
      }
      node=stack.pop();
      node=node.lastElementChild;
    }
  };

非递归实现二叉 DOM 树的中序遍历

Tree.prototype.inOrder = function(node,callback) {
    var stack=[];
    while(node!== null || stack.length!=0){
      while(node!==null){
        stack.push(node);
        node=node.firstElementChild;
      }
      node=stack.pop();
      callback(node);
      node=node.lastElementChild;
    }
  };

非递归实现二叉 DOM 树的后序遍历

① 每个节点,都压入栈两次;
② 在循环体中,每次弹出一个节点赋给node
③ 如果node仍然等于栈的头结点,说明node的孩子们还没有被操作过,应该把它的孩子们加入栈中
④ 否则,说明是第二次弹出该节点,访问node。

也就是说,第一次弹出,将node的孩子压入栈中,第二次弹出,访问node

TreeWalker.prototype.postOrder = function(node,callback) {//非递归实现
  var stack=[];
    stack.push(node);
    stack.push(node);
  while(stack.length != 0)
  {
    node = stack.pop();
    if(stack.length != 0 && node==stack[stack.length-1])
    {
      if(node.lastElementChild) stack.push(node.lastElementChild), stack.push(node.lastElementChild);
      if(node.firstElementChild) stack.push(node.firstElementChild), stack.push(node.firstElementChild);
    }
    else
        callback(node);
  }
}

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
用jscript实现新建word文档
Jun 15 Javascript
jQuery1.5.1 animate方法源码阅读
Apr 05 Javascript
jQuery实现可收缩展开的级联菜单实例代码
Nov 27 Javascript
JsRender实用入门教程
Oct 31 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
Oct 13 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
Nov 24 Javascript
微信小程序 label 组件详解及简单实例
Jan 10 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
Feb 28 Javascript
在layui tab控件中载入外部html页面的方法
Sep 04 Javascript
JavaScript代理模式原理与用法实例详解
Mar 10 Javascript
javascript 内存模型实例详解
Apr 18 Javascript
element跨分页操作选择详解
Jun 29 Javascript
Vue 实现树形视图数据功能
May 07 #Javascript
JavaScript 跨域之POST实现方法
May 07 #Javascript
ES6关于Promise的用法详解
May 07 #Javascript
React Form组件的实现封装杂谈
May 07 #Javascript
vue如何将v-for中的表格导出来
May 07 #Javascript
浅谈Vue 数据响应式原理
May 07 #Javascript
浅谈Vue响应式(数组变异方法)
May 07 #Javascript
You might like
phpBB BBcode处理的漏洞
2006/10/09 PHP
使用PHP 5.0创建图形的巧妙方法
2010/10/12 PHP
php 伪造本地文件包含漏洞的代码
2011/11/03 PHP
使用php统计字符串中中英文字符的个数
2013/06/23 PHP
深入PHP许愿墙模块功能分析
2013/06/25 PHP
php使用ereg验证文件上传的方法
2014/12/16 PHP
对于Form表单reset方法的新认识
2014/03/05 Javascript
10个很棒的jQuery代码片段
2015/09/24 Javascript
JavaScript判断数字是否为质数的方法汇总
2016/06/02 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
微信小程序地图(map)组件点击(tap)获取经纬度的方法
2019/01/10 Javascript
实例分析编写vue组件方法
2019/02/12 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
python解析xml文件实例分享
2013/12/04 Python
Python argv用法详解
2016/01/08 Python
Java实现的执行python脚本工具类示例【使用jython.jar】
2018/03/29 Python
致Python初学者 Anaconda入门使用指南完整版
2018/04/05 Python
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
2018/05/22 Python
python+opencv3生成一个自定义纯色图教程
2020/02/19 Python
有趣的Python图片制作之如何用QQ好友头像拼接出里昂
2020/04/22 Python
巧用CSS3 border实现图片遮罩效果代码
2012/04/09 HTML / CSS
iframe在移动端的缩放的示例代码
2018/10/12 HTML / CSS
深入理解HTML5定时器requestAnimationFrame的使用
2018/12/12 HTML / CSS
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
表彰会主持词
2014/03/26 职场文书
装配出错检讨书
2014/09/23 职场文书
客房领班岗位职责
2015/02/11 职场文书
2015年度优秀员工自荐书
2015/03/06 职场文书
欠款证明
2015/06/24 职场文书
机关单位2016年创先争优活动总结
2016/04/05 职场文书
解决pytorch-gpu 安装失败的记录
2021/05/24 Python
Pycharm连接远程服务器并远程调试的全过程
2021/06/24 Python
零基础学java之带参数以及返回值的方法
2022/04/10 Java/Android