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 相关文章推荐
checkbox全选/取消全选以及checkbox遍历jQuery实现代码
Dec 02 Javascript
九种js弹出对话框的方法总结
Mar 12 Javascript
jQuery表单域属性过滤器用法分析
Feb 10 Javascript
JavaScript实现自动生成网页元素功能(按钮、文本等)
Nov 21 Javascript
Vue.js实现无限加载与分页功能开发
Nov 03 Javascript
详解如何使用Vue2做服务端渲染
Mar 29 Javascript
无循环 JavaScript(map、reduce、filter和find)
Apr 08 Javascript
Angular.js中定时器循环的3种方法总结
Apr 27 Javascript
js使用generator函数同步执行ajax任务
Sep 05 Javascript
React中使用async validator进行表单验证的实例代码
Aug 17 Javascript
在antd中setFieldsValue和defaultVal的用法
Oct 29 Javascript
webpack的移动端适配方案小结
Jul 25 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
PHP5 安装方法
2007/01/15 PHP
PHP的加密方式及原理
2012/06/14 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
2016/11/14 PHP
浅析php中array_map和array_walk的使用对比
2016/11/20 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
Javascript 键盘keyCode键码值表
2009/12/24 Javascript
js Array对象的扩展函数代码
2013/04/24 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
2013/07/01 Javascript
node.js中的path.isAbsolute方法使用说明
2014/12/08 Javascript
Node.js 学习笔记之简介、安装及配置
2015/03/03 Javascript
jquery 插件实现瀑布流图片展示实例
2015/04/03 Javascript
js中日期的加减法
2015/05/06 Javascript
js实现内容显示并使用json传输数据
2016/03/16 Javascript
基于BootStrap的图片轮播效果展示实例代码
2016/05/23 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
AngularJS基础 ng-switch 指令简单示例
2016/08/03 Javascript
浅谈jQuery this和$(this)的区别及获取$(this)子元素对象的方法
2016/11/29 Javascript
JS实现的数组去除重复数据算法小结
2017/11/17 Javascript
vue-router命名路由和编程式路由传参讲解
2019/01/19 Javascript
ES6基础之解构赋值(destructuring assignment)
2019/02/21 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
vue实现图书管理系统
2020/12/29 Vue.js
跟老齐学Python之??碌某?? target=
2014/09/12 Python
python通过yield实现数组全排列的方法
2015/03/18 Python
Python paramiko模块的使用示例
2018/04/11 Python
解读python logging模块的使用方法
2018/04/17 Python
python中的turtle库函数简单使用教程
2018/07/23 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
matlab中imadjust函数的作用及应用举例
2020/02/27 Python
利用python爬取有道词典的方法
2020/12/08 Python
幼儿园家长评语
2014/02/10 职场文书
餐厅采购员岗位职责
2014/03/06 职场文书
个人授权委托书范本
2014/04/03 职场文书
求职自荐信怎么写
2015/03/04 职场文书
教你用Java Swing实现自助取款机系统
2021/06/11 Java/Android