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 相关文章推荐
JSuggest自动匹配下拉框使用方法(示例代码)
Dec 27 Javascript
后台获取ZTREE选中节点的方法
Feb 12 Javascript
基于Bootstrap实现tab标签切换效果
Apr 15 Javascript
vue.js实现含搜索的多种复选框(附源码)
Mar 23 Javascript
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
Dec 07 Javascript
JS实现的抛物线运动效果示例
Jan 30 Javascript
彻底理解js面向对象之继承
Feb 04 Javascript
vue.js动画中的js钩子函数的实现
Jul 06 Javascript
JQuery实现简单的复选框树形结构图示例【附源码下载】
Jul 16 jQuery
JavaScript冒泡算法原理与实现方法深入理解
Jun 04 Javascript
微信小程序绘制半圆(弧形)进度条
Nov 18 Javascript
jQuery实现可以扩展的日历
Dec 01 jQuery
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
一个用php3编写的简单计数器
2006/10/09 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
基于php常用函数总结(数组,字符串,时间,文件操作)
2013/06/27 PHP
php解析url的三个示例
2014/01/20 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
很酷的javascript loading效果代码
2008/06/18 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
js表单提交和submit提交的区别实例分析
2015/12/10 Javascript
基于Javascript实现弹出页面效果
2016/01/01 Javascript
Bootstrap每天必学之轮播(Carousel)插件
2016/04/25 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
值得分享的Bootstrap Table使用教程
2016/11/23 Javascript
jQuery实现的老虎机跑动效果示例
2018/12/29 jQuery
Vue中Axios从远程/后台读取数据
2019/01/21 Javascript
react的滑动图片验证码组件的示例代码
2019/02/27 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
微信小程序调用wx.getImageInfo遇到的坑解决
2020/05/31 Javascript
python中List的sort方法指南
2014/09/01 Python
python 借助numpy保存数据为csv格式的实现方法
2018/07/04 Python
Python实现分段线性插值
2018/12/17 Python
如何安装并使用conda指令管理python环境
2019/07/10 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
简单了解python变量的作用域
2019/07/30 Python
深入理解Tensorflow中的masking和padding
2020/02/24 Python
让IE6、IE7、IE8支持CSS3的脚本
2010/07/20 HTML / CSS
美国网上花店:JustFlowers
2017/02/12 全球购物
东方通信股份有限公司VC面试题
2014/08/27 面试题
4s店销售经理岗位职责
2014/07/19 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
律师授权委托书范本
2014/10/07 职场文书
2015入党自荐书范文
2015/03/05 职场文书
爱国电影观后感
2015/06/19 职场文书
Python趣味挑战之用pygame实现简单的金币旋转效果
2021/05/31 Python
mysql数据库实现设置字段长度
2022/06/10 MySQL