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 相关文章推荐
JS 日期验证正则附asp日期格式化函数
Sep 11 Javascript
基于JQuery制作的产品广告效果
Dec 08 Javascript
jQuery总体架构的理解分析
Mar 07 Javascript
Javascript中判断变量是数组还是对象(array还是object)
Aug 14 Javascript
详解JS函数重载
Dec 04 Javascript
JavaScript实现网页对象拖放功能的方法
Apr 15 Javascript
jQuery使用ajax跨域获取数据的简单实例
May 18 Javascript
jQuery插件FusionCharts实现的3D柱状图效果实例【附demo源码下载】
Mar 03 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
Sep 13 Javascript
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
Jan 18 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
Apr 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
PHP实现单例模式最安全的做法
2014/06/13 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
php生成动态验证码gif图片
2015/10/19 PHP
PHP基于swoole多进程操作示例
2019/08/12 PHP
javascript(jquery)利用函数修改全局变量的代码
2009/11/02 Javascript
基于jQuery的可以控制左右滚动及自动滚动效果的代码
2010/07/25 Javascript
jquery子元素过滤选择器使用示例
2013/06/24 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
详解javascript实现瀑布流列式布局
2016/01/29 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
2016/08/02 Javascript
利用VUE框架,实现列表分页功能示例代码
2017/01/12 Javascript
jquery实时获取时间的简单实例
2017/01/26 Javascript
Vue2.0 UI框架ElementUI使用方法详解
2017/04/14 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
2018/05/16 Javascript
JS闭包原理与应用经典示例
2018/12/20 Javascript
使用 node.js 模仿 Apache 小部分功能
2019/07/07 Javascript
vue实现淘宝购物车功能
2020/04/20 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
2020/05/14 Javascript
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
python中实现迭代器(iterator)的方法示例
2017/01/19 Python
浅谈Python采集网页时正则表达式匹配换行符的问题
2018/12/20 Python
Django中信号signals的简单使用方法
2019/07/04 Python
python模拟实现斗地主发牌
2020/01/07 Python
python操作ini类型配置文件的实例教程
2020/10/30 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
eBay澳大利亚站:eBay.com.au
2018/02/02 全球购物
Love, Bonito国际官网:新加坡女装品牌
2021/03/13 全球购物
营销人才自我鉴定范文
2013/12/25 职场文书
淘宝客服自我总结鉴定
2014/01/25 职场文书
廉洁自律承诺书
2014/03/27 职场文书
个人查摆剖析材料
2014/10/16 职场文书
委托公证书样本
2015/01/23 职场文书
关于应聘教师的自荐信
2016/01/28 职场文书
【海涛解说】史上最给力比赛,挑战DOTA极限
2022/04/01 DOTA