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小玩意 几个属性相加不能超过一个特定值.
Sep 29 Javascript
精选的10款用于构建良好易用性网站的jQuery插件
Jan 23 Javascript
关于jQuery中的each方法(jQuery到底干了什么)
Mar 05 Javascript
jQuery修改CSS伪元素属性的方法
Jul 30 Javascript
原生javascript实现隔行换色
Jan 04 Javascript
jQuery插件Skippr实现焦点图幻灯片特效
Apr 12 Javascript
jQuery图片旋转插件jQueryRotate.js用法实例(附demo下载)
Jan 21 Javascript
浅谈jQuery添加的HTML,JS失效的问题
Oct 05 Javascript
javascript滚轮控制模拟滚动条
Oct 19 Javascript
js获取时间函数及扩展函数的方法
Oct 30 Javascript
JavaScript从原型到原型链深入理解
Jun 03 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
Mar 10 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面向对象全攻略 (九)访问类型
2009/09/30 PHP
使用phpQuery采集网页的方法
2013/11/13 PHP
php采集中国代理服务器网的方法
2015/06/16 PHP
YII分模块加载路由的实现方法
2018/10/01 PHP
Laravel修改验证提示信息为中文的示例
2019/10/23 PHP
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
laydate 显示结束时间不小于开始时间的实例
2017/08/11 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
angular实现页面打印局部功能的思考与方法
2018/04/13 Javascript
JavaScript控制浏览器全屏显示简单示例
2018/07/05 Javascript
使用Vue实现图片上传的三种方式
2018/07/17 Javascript
vue+mousemove实现鼠标拖动功能(拖动过快失效问题解决方法)
2018/08/24 Javascript
浅析vue-router原理
2018/10/19 Javascript
详解微信小程序中组件通讯
2018/10/30 Javascript
微信小程序实现时间预约功能
2018/11/27 Javascript
微信小程序点击保存图片到本机功能
2019/12/13 Javascript
vue中keep-alive内置组件缓存的实例代码
2020/04/16 Javascript
JS实现悬浮球只在一侧滑动并且是横屏状态下
2020/08/19 Javascript
Python内置函数dir详解
2015/04/14 Python
Python 私有函数的实例详解
2017/09/11 Python
对pandas进行数据预处理的实例讲解
2018/04/20 Python
机器学习实战之knn算法pandas
2019/06/22 Python
Python 之 Json序列化嵌套类方式
2020/02/27 Python
Python Scrapy框架:通用爬虫之CrawlSpider用法简单示例
2020/04/11 Python
Pandas将列表(List)转换为数据框(Dataframe)
2020/04/24 Python
python 如何引入协程和原理分析
2020/11/30 Python
美国娱乐和流行文化商品店:FYE
2017/09/14 全球购物
香蕉共和国工厂店:Banana Republic Factory
2018/06/09 全球购物
为娇小女性量身打造:Petite Studio
2018/11/01 全球购物
EJB的几种类型
2012/08/15 面试题
授权委托书范文
2014/07/31 职场文书
日本十大血腥动漫,那些被禁播的动漫盘点
2022/03/21 日漫
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python