<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>深度遍历和广度遍历测试</title>
<style type="text/css"> </style>
</head>
<body>
<div class="box">
<ul class="menus">
<li class="item1"><i class="item1-icon"></i><span class="item1-content">菜单1</span></li>
<li class="item2"><i class="item2-icon"></i><span class="item2-content">菜单2</span></li>
<li class="item3"><i class="item3-icon"></i><span class="item3-content">菜单3</span></li>
</ul>
</div>
<script>
console.log('深度优先递归');
DFTRecur(document.body,[],function(item){
console.log(item);
}); console.log('深度优先非递归');
let res = DFT(Array.from(document.body.children),function(item){
// if(item.className == 'item2-content'){
// console.log('taget item', item);
// return true;
// }
console.log(item);
}); console.log('广度优先递归');
BFTRec(document.body,[]); console.log('广度优先非递归');
BFT(Array.from(document.body.children)); //深度优先搜索的递归写法
function DFSRecur(root,stack,fVistor) {
let b = false;
if (root != null) {
stack.push(root);
//函数fVistor,节点传入函数,节点一旦满足某种条件,就返回true
//可以在找到第一个满足条件的节点后,就停止遍历
if(fVistor(root))return true; var children = root.children;
if(children){
for (var i = 0; i < children.length; i++){
b = DFTRecur(children[i],stack,fVistor);
//有一个子节点满足条件就停止循环
if(b) break;
}
}
//当前节点及其子节点都不满足条件就出栈
if(!b) stack.pop();
}
return b;
} //深度优先遍历的递归写法,深度优先遍历递归,不需要使用栈,通常是使用先序遍历,即先遍历根节点,再遍历所有子节点
function DFSRecur(root,stack,fVistor) {
if (root != null) {
fVistor(root) var children = root.children;
if(children){
for (var i = 0; i < children.length; i++){
DFTRecur(children[i],stack,fVistor);
}
}
}
} //深度优先遍历的非递归写法
function DFT(root,fVistor) {
fVistor = fVistor || console.log;
if (root != null) {
//兼容root为数组,且从前往后深度遍历
var stack = [].concat(root).reverse(); while (stack.length != 0) {
var item = stack.pop();
//满足条件就break,使得方法兼具深度优先搜索的功能,找到就跳出循环,停止查找
if(fVistor(item)) break;if(item.children) stack.push(...Array.from(item.children).reverse());
}
}
} //广度优先遍历的递归写法,广度优先的递归和非递归写法都需要队列
function BFTRec(root,queue,fVistor){
fVistor = fVistor || console.log;
if(root != null){
queue.push(root);
//满足条件return,使该方法兼具广度优先搜索的功能,找到就停止遍历
if(fVistor(root)) return;
//先访问下一个兄弟节点,递归会一直横向访问,直至横向访问完毕
BFTRec(root.nextElementSibling,queue,fVistor);
//回到本行的第一个节点root
root = queue.shift();
//跳到root节点的下一行的第一个节点,又会开始横向遍历
BFTRec(root.firstElementChild,queue,fVistor);
}
} //广度优先遍历的非递归写法
function BFT(root,fVistor) {
fVistor = fVistor || console.log;
if (root != null) {
//兼容root为数组情况
var queue = [].concat(root);
while (queue.length != 0) {
var item = queue.shift();
//找到就break,使得方法兼具广度优先搜索功能,找到就停止遍历
if(fVistor(item)) break;
if(item.children) queue.push(...item.children);
}
}
}
</script>
</body>
</html>

Dom的深度优先遍历和广度优先遍历的更多相关文章

  1. 深度优先遍历 and 广度优先遍历

    深度优先遍历 and 广度优先遍历 遍历在前端的应用场景不多,多数是处理DOM节点数或者 深拷贝.下面笔者以深拷贝为例,简单说明一些这两种遍历.

  2. js实现深度优先遍历和广度优先遍历

    深度优先遍历和广度优先遍历 什么是深度优先和广度优先 其实简单来说 深度优先就是自上而下的遍历搜索 广度优先则是逐层遍历, 如下图所示 1.深度优先 2.广度优先 两者的区别 对于算法来说 无非就是时 ...

  3. C++ 二叉树深度优先遍历和广度优先遍历

    二叉树的创建代码==>C++ 创建和遍历二叉树 深度优先遍历:是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. //深度优先遍历二叉树void depthFirstSearch(Tree r ...

  4. 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

    matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...

  5. C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构 1)邻接矩阵 用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息. 2)邻接表 3)十字链表 4)邻接多重表 5)边集数组 本文只用代码实现用 ...

  6. js实现对树深度优先遍历与广度优先遍历

    深度优先与广度优先的定义 首先我们先要知道什么是深度优先什么是广度优先. 深度优先遍历是指从某个顶点出发,首先访问这个顶点,然后找出刚访问这个结点的第一个未被访问的邻结点,然后再以此邻结点为顶点,继续 ...

  7. python、java实现二叉树,细说二叉树添加节点、深度优先(先序、中序、后续)遍历 、广度优先 遍历算法

    数据结构可以说是编程的内功心法,掌握好数据结构真的非常重要.目前基本上流行的数据结构都是c和c++版本的,我最近在学习python,尝试着用python实现了二叉树的基本操作.写下一篇博文,总结一下, ...

  8. 【图的遍历】广度优先遍历(DFS)、深度优先遍历(BFS)及其应用

    无向图满足约束条件的路径 •[目的]:掌握深度优先遍历算法在求解图路径搜索问题的应用 [内容]:编写一个程序,设计相关算法,从无向图G中找出满足如下条件的所有路径:  (1)给定起点u和终点v.  ( ...

  9. 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]

    深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点 ...

随机推荐

  1. CentOS 系统 Docker 的命令大全

    本文记录 CentOS 系统 Docker 的命令大全 命令 docker ps 显示运行中的容器 docker ps -a 显示所有容器 docker start 容器名称 启动容器 docker ...

  2. Linux终端显示控制字符

    在Linux中, 我们时常要将一个命令的输出作为另外一个命令的输入进行下一步处理操作. 有时, 如果一个命令的输出中有不可见的控制字符时, 有可能会导致后续操作出错. 而这些控制字符很可能是不可打印的 ...

  3. JDK5 新特性

     JDK5新特性目录导航: 自动拆装箱 Foreach 静态导入 可变参数 Var args 枚举 格式化输出 泛型 ProcessBuilder 内省 线程并发库(JUC) 监控和管理虚拟机 元数据 ...

  4. MySQL创建民族表的SQL语句

    MySQL创建民族表的SQL语句 CREATE TABLE `nation` ( `id` ) unsigned NOT NULL AUTO_INCREMENT, `nation` ) NOT NUL ...

  5. MySQL查询优化 对not in 、in 的优化

    因为 not in不走索引,所以不在不得已情况下,就不要使用not in 下面使用 join 来替代not in 做查询 select ID from A where ID not in (selec ...

  6. C#简单的文件阅读器

    写一个简单的文件阅读器  1.可以读取大文件(2G)2.实现首页.下一页.前一页.末页的跳转3.实现到指定页面的跳转,比如跳转到第**页4.限制每页显示字符数 1029-4069byte,且用户可自定 ...

  7. Fruits【水果】

    Fruits Many of us love July because it's the month when nature's berries and stone fruits are in abu ...

  8. B1091 N-自守数 (15分)

    B1091 N-自守数 (15分) 如果某个数 \(K\)的平方乘以\(N\) 以后,结果的末尾几位数等于 \(K\),那么就称这个数为"\(N\)-自守数".例如 \(3×92 ...

  9. c++ 计算器 带括号 代码实现

    我用了两个栈 一个用来存数字 一个用来存运算符 这里引入优先度的概念便于理解 不同的运算符有不同的优先度 当优先度高的符号进入栈中 所有比它优先度低的符号都要弹出 对 就是这么霸道 ( 没有优先度 没 ...

  10. 如何使用Python脚本

    来自官方文档 一.写 python 脚本: import sys import datetime for line in sys.stdin: line = line.strip() userid, ...