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 相关文章推荐
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
Mar 21 Javascript
js动态创建、删除表格示例代码
Aug 07 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
Nov 11 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
Mar 03 Javascript
Javascript Object 对象学习笔记
Dec 17 Javascript
js H5 canvas投篮小游戏
Aug 18 Javascript
jQuery中JSONP的两种实现方式详解
Sep 26 Javascript
JavaScript for循环 if判断语句(学习笔记)
Oct 11 Javascript
详解vue-cli 脚手架 安装
Apr 16 Javascript
微信小程序 弹窗输入组件的实现解析
Aug 12 Javascript
Vue过滤器(filter)实现及应用场景详解
Jun 15 Vue.js
Vue3中的Refs和Ref详情
Nov 11 Vue.js
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 各种排序算法实现代码
2009/08/20 PHP
php提示Call-time pass-by-reference has been deprecated in的解决方法[已测]
2012/05/06 PHP
php实现ip白名单黑名单功能
2015/03/12 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
js压缩利器
2007/02/20 Javascript
Javascript中Eval函数的使用说明
2008/10/11 Javascript
JQuery 选项卡效果(JS与HTML的分离)
2010/04/01 Javascript
javascript getElementsByTagName
2011/01/31 Javascript
一个js导致的jquery失效问题的解决方法
2013/11/27 Javascript
javascript创建动态表单的方法
2015/07/25 Javascript
js控件Kindeditor实现图片自动上传功能
2020/07/20 Javascript
JS获取鼠标相对位置的方法
2016/09/20 Javascript
修改ligerui 默认确认按钮的方法
2016/12/27 Javascript
JavaScript new对象的四个过程实例浅析
2018/07/31 Javascript
解决v-for中使用v-if或者v-bind:class失效的问题
2018/09/25 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
2019/10/24 Javascript
你准备好迎接vue3.0了吗
2020/04/28 Javascript
[03:05]DOTA2英雄基础教程 嗜血狂魔
2013/12/10 DOTA
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
Python读取Excel表格,并同时画折线图和柱状图的方法
2018/10/14 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
FC-Moto西班牙:摩托车手最大的购物场所之一
2019/04/11 全球购物
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
公司行政经理岗位职责
2013/12/24 职场文书
11月升旗仪式讲话稿
2014/02/15 职场文书
关心下一代工作先进事迹
2014/08/15 职场文书
妈妈活动方案
2014/08/15 职场文书
2014年国庆节广播稿
2014/09/19 职场文书
退学证明范本3篇
2014/10/29 职场文书
儿园租房协议书范本
2014/12/02 职场文书
节水宣传标语口号
2015/12/26 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
pytorch常用数据类型所占字节数对照表一览
2021/05/17 Python
windows11选中自动复制怎么开启? Win11自动复制所选内容的方法
2022/07/23 数码科技