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对象数组按属性快速排序
Jan 31 Javascript
jquery中防刷IP流量软件影响统计的一点对策
Jul 10 Javascript
js冒泡、捕获事件及阻止冒泡方法详细总结
May 08 Javascript
JavaScript数据结构与算法之栈详解
Mar 12 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
详解JavaScript中Hash Map映射结构的实现
May 21 Javascript
jQuery中事件与动画的总结分享
May 24 Javascript
如何快速上手Vuex
Feb 14 Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
Mar 09 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
JavaScript ES6中的简写语法总结与使用技巧
Dec 30 Javascript
Vue插件之滑动验证码用法详解
Apr 05 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+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
php连接Access数据库错误及解决方法
2013/06/20 PHP
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
php网页版聊天软件实现代码
2016/08/12 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
2018/09/03 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
Web开发者必备的12款超赞jQuery插件
2010/12/03 Javascript
javascript 进阶篇2 CSS XML学习
2012/03/14 Javascript
window.location不跳转的问题解决方法
2014/04/17 Javascript
SuperSlide2实现图片滚动特效
2014/06/20 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
2015/06/05 Javascript
jquery+json实现数据二级联动的方法
2015/11/28 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
学习使用bootstrap基本控件(table、form、button)
2016/04/12 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
浅谈JS函数定义方式的区别
2016/10/30 Javascript
小发现之浅谈location.search与location.hash的问题
2017/06/23 Javascript
微信小程序使用checkbox显示多项选择框功能【附源码下载】
2017/12/11 Javascript
深入理解Node内建模块和对象
2019/03/12 Javascript
vue使用代理解决请求跨域问题详解
2019/07/24 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
2018/04/19 Python
python中pip的安装与使用教程
2018/08/10 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
法国房车租赁网站:Yescapa
2019/08/26 全球购物
护理职业生涯规划书
2014/01/24 职场文书
双语教学实施方案
2014/03/23 职场文书
捐资助学感谢信
2015/01/21 职场文书
2020年个人安全保证书参考模板
2020/01/08 职场文书
Java基础之线程锁相关知识总结
2021/06/30 Java/Android
Python  序列化反序列化和异常处理的问题小结
2022/12/24 Python