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 相关文章推荐
短信提示使用 特效
Jan 19 Javascript
编写Js代码要注意的几条规则
Sep 10 Javascript
Javascript 面向对象(三)接口代码
May 23 Javascript
设置checkbox为只读(readOnly)的两种方式
Oct 11 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
jQuery中offset()方法用法实例
Jan 16 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
解决微信内置浏览器返回上一页强制刷新问题方法
Feb 05 Javascript
bootstrap table合并行数据并居中对齐效果
Oct 17 Javascript
JavaScript遍历DOM元素的常见方式示例
Feb 16 Javascript
javascript关于“时间”的一次探索
Jul 24 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
Jul 21 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
PHP 数组遍历顺序理解
2009/09/09 PHP
php使用google地图应用实例
2014/12/31 PHP
Laravel SQL语句记录方式(推荐)
2016/05/26 PHP
php时间函数用法分析
2016/05/28 PHP
js压缩利器
2007/02/20 Javascript
JS 字符串连接[性能比较]
2009/05/10 Javascript
juqery 学习之四 筛选过滤
2010/11/30 Javascript
有关javascript的性能优化 (repaint和reflow)
2013/04/12 Javascript
Jquery通过Ajax方式来提交Form表单的具体实现
2013/11/07 Javascript
JS测试显示屏分辨率以及屏幕尺寸的方法
2013/11/22 Javascript
JavaScript异步加载浅析
2014/12/28 Javascript
理解JavaScript的变量的入门教程
2015/07/07 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
2015/08/17 Javascript
antd Upload 文件上传的示例代码
2018/12/14 Javascript
angularjs1.X 重构controller 的方法小结
2019/08/15 Javascript
[01:04:09]DOTA2-DPC中国联赛 正赛 iG vs VG BO3 第二场 2月2日
2021/03/11 DOTA
使用Python的Treq on Twisted来进行HTTP压力测试
2015/04/16 Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
浅析Python中元祖、列表和字典的区别
2016/08/17 Python
Python用csv写入文件_消除空余行的方法
2018/07/06 Python
对Python中DataFrame选择某列值为XX的行实例详解
2019/01/29 Python
python pytest进阶之conftest.py详解
2019/06/27 Python
Python+OpenCV实现实时眼动追踪的示例代码
2019/11/11 Python
python打开音乐文件的实例方法
2020/07/21 Python
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
瑞典时尚耳机品牌:Urbanears
2017/07/26 全球购物
构造方法和其他方法的区别?怎么调用父类的构造方法
2013/09/22 面试题
简短的公司员工自我评价分享
2013/11/13 职场文书
餐饮投资计划书
2014/04/25 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
商务经理岗位职责
2014/08/03 职场文书
班子群众路线教育实践个人对照检查材料思想汇报
2014/09/30 职场文书
员工工作心得体会
2019/05/07 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
MySQL 使用事件(Events)完成计划任务
2021/05/24 MySQL