<!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. Github学生包的申请

    Github Education为了大学生们更好的进行开发,进行边做边学,与一些合作伙伴和朋友一起创建GitHub学生开发者包. 里面内容非常丰富,应有尽有: AWS 亚马逊云服务 $75-$150  ...

  2. ZJOI2019Round#2

    乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v​\)使得两棵树中\((u,v)​\)距离的和最大. ...

  3. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  4. python中的字符串内置方法小结

    #!/usr/local/bin/python3 # -*- coding:utf-8 -*- ''' name="my wife is mahongyan" ---------- ...

  5. 输入cin对象的用法

    #include<iostream> using namespace std; int main() { int carrots ; cout << "How man ...

  6. Poweroj:2425-跳台阶(经典递推)

    题目链接:https://www.oj.swust.edu.cn/problem/show/2425 跳台阶 Edit Manage Data Rejudge Time Limit: 1000 MS ...

  7. 笔记-select,poll,epoll

    笔记-select,poll,epoll 1.      I/O多路复用 I/O多路复用是指:通过一种机制或一个进程,可以监视多个文件描述符,一旦描述符就绪(写或读),能够通知程序进行相应的读写操作. ...

  8. Ubuntu 16.04上安装并配置Postfix作为只发送SMTP服务器

    如果大家已经在使用第三方邮件服务方案发送并收取邮件,则无需运行自己的邮件服务器.然而,如果大家管理一套云服务器,且其中安装的应用需要发送邮件通知,那么运行一套本地只发送SMTP服务器则更为理想. 如何 ...

  9. GPIO基础知识

    STM32 GPIO入门知识 GPIO是什么? 通用输入输出端口,可以做输入,也可以做输出.GPIO端口可通过程序配置成输入或输出. 引脚和GPIO的区别和联系 STM32的引脚中,有部分是做GPIO ...

  10. ListView getChildCount 以及getChildAt 坑 误区指南

    今天调试的时候,才知道. 原来listview 的 getChildCount 取得是当前可先的list item 的个数,而不是整个listview 的count. 整个listview 的数量应该 ...