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 相关文章推荐
将CKfinder整合进CKEditor3.0的新方法
Jan 10 Javascript
jQuery EasyUI API 中文文档 - ComboGrid 组合表格
Oct 13 Javascript
js实现从中间开始往上下展开网页窗口的方法
Mar 02 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
Mar 27 Javascript
js实现的光标位置工具函数示例
Oct 03 Javascript
微信小程序 devtool隐藏的秘密
Jan 21 Javascript
Angular2使用Augury来调试Angular2程序
May 21 Javascript
AngularJS 打开新的标签页实现代码
Sep 07 Javascript
vue-cli3全面配置详解
Nov 14 Javascript
vue接入腾讯防水墙代码
May 07 Javascript
VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法
Apr 17 Javascript
解决vue安装less报错Failed to compile with 1 errors的问题
Oct 22 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 AJAX实例根据邮编自动完成地址信息
2008/11/23 PHP
PHP 最大运行时间 max_execution_time修改方法
2010/03/08 PHP
php curl模拟post请求小实例
2013/11/13 PHP
PHP对象递归引用造成内存泄漏分析
2014/08/28 PHP
php中动态调用函数的方法
2015/03/16 PHP
PHP中array_keys和array_unique函数源码的分析
2016/02/26 PHP
PHP的mysqli_sqlstate()函数讲解
2019/01/23 PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
2020/03/16 PHP
JS Replace()的高级使用方法介绍
2013/06/29 Javascript
javascript+html5实现绘制圆环的方法
2015/07/28 Javascript
springMVC结合AjaxForm上传文件
2016/07/12 Javascript
js实现非常棒的弹出div
2016/10/06 Javascript
微信小程序 空白页重定向解决办法
2017/06/27 Javascript
ES6 javascript中class类的get与set用法实例分析
2017/10/30 Javascript
记一次webapck4 配置文件无效的解决历程
2018/09/19 Javascript
WEB前端性能优化的7大手段详解
2020/02/04 Javascript
通过javascript实现扫雷游戏代码实例
2020/02/09 Javascript
antd vue 刷新保留当前页面路由,保留选中菜单,保留menu选中操作
2020/08/06 Javascript
vue项目实现设置根据路由高亮对应的菜单项操作
2020/08/06 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
[42:25]EG vs Spirit Supermajor 败者组 BO3 第二场 6.4
2018/06/05 DOTA
Python制作钉钉加密/解密工具
2016/12/07 Python
在VS Code上搭建Python开发环境的方法
2018/04/06 Python
python 列表,数组和矩阵sum的用法及区别介绍
2018/06/28 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
python itchat给指定联系人发消息的方法
2019/06/11 Python
pytorch的梯度计算以及backward方法详解
2020/01/10 Python
PyQt5-QDateEdit的简单使用操作
2020/07/12 Python
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
法国珠宝店:CLEOR
2017/01/29 全球购物
美国知名艺术画网站:Art.com
2017/02/09 全球购物
匈牙利墨盒和碳粉购买网站:CDRmarket
2018/04/14 全球购物
lululemon美国官网:瑜伽服+跑步装备
2018/11/16 全球购物
俄罗斯最大的灯具网站:Fandeco
2020/03/14 全球购物
adidas马来西亚官网:adidas MY
2020/09/12 全球购物
2014城乡环境综合治理工作总结
2014/12/19 职场文书