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 相关文章推荐
event对象获取方法总结在google浏览器下测试
Nov 03 Javascript
深入探寻javascript定时器
Jan 02 Javascript
JavaScript使用二分查找算法在数组中查找数据的方法
Apr 07 Javascript
js图片轮播效果实现代码
Apr 18 Javascript
Knockout自定义绑定创建方法
Dec 26 Javascript
jquery.validate提示错误信息位置方法
Jan 22 Javascript
jQuery中Ajax全局事件引用方式及各个事件(全局/局部)执行顺序
Jun 02 Javascript
图文详解Javascript中的上下文和作用域
Feb 15 Javascript
JS实现百度搜索框关键字推荐
Feb 17 Javascript
JS eval代码快速解密实例解析
Apr 23 Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 Javascript
vue中的可拖拽宽度div的实现示例
Apr 08 Vue.js
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的SQL注入实现(测试代码安全不错)
2011/02/27 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
php实现将base64格式图片保存在指定目录的方法
2016/10/13 PHP
php 调用ffmpeg获取视频信息的简单实现
2017/04/03 PHP
PHP+redis实现的购物车单例类示例
2019/02/02 PHP
解决laravel中日志权限莫名变成了root的问题
2019/10/17 PHP
使用git迁移Laravel项目至新开发环境的步骤详解
2020/04/06 PHP
JavaScript中的几个关键概念的理解-原型链的构建
2011/05/12 Javascript
JS实现部分HTML固定页面顶部随屏滚动效果
2015/12/24 Javascript
Jquery轮播效果实现过程解析
2016/03/30 Javascript
巧用jQuery选择器提高写表单效率的方法
2016/08/19 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
axios进阶实践之利用最优雅的方式写ajax请求
2017/12/20 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
2018/02/01 Javascript
详解基于mpvue的小程序markdown适配解决方案
2018/05/08 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
2019/01/24 Javascript
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
尝试用最短的Python代码来实现服务器和代理服务器
2016/06/23 Python
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
python 与GO中操作slice,list的方式实例代码
2017/03/20 Python
解决python3 requests headers参数不能有中文的问题
2019/08/21 Python
python生成器用法实例详解
2019/11/22 Python
python 写一个文件分发小程序
2020/12/05 Python
AVON雅芳官网:世界上最大的美容化妆品公司之一
2016/11/02 全球购物
韩国11街:11STREET
2018/03/27 全球购物
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
写好求职信第一句话的技巧
2013/10/26 职场文书
简单英文演讲稿
2014/01/01 职场文书
文明礼仪伴我行演讲稿
2014/05/12 职场文书
2014年客服工作总结与计划
2014/12/09 职场文书
2014年绩效考核工作总结
2014/12/11 职场文书
幸福来敲门观后感
2015/06/04 职场文书
销售人员管理制度
2015/08/06 职场文书
清明节主题班会
2015/08/14 职场文书
css 中多种边框的实现小窍门
2021/04/07 HTML / CSS
apache虚拟主机配置的三种方式(小结)
2022/07/23 Servers