C#,深度优先搜索(DFS)、广度优先搜索(BFS)算法的源代码与数据可视化

news2024/11/6 7:06:19

概述

下载源代码:

链接:https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd=2kwl 提取码:2kwl --来自百度网盘超级会员V5的分享icon-default.png?t=N7T8https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd=2kwl

深度优先搜索(亦称深度优先遍历,Deep First Search,简称DFS),广度优先搜索(亦称广度优先遍历,Breadth First Search,简称BFS)都是很基础的算法,也是大家很熟悉的。

先看一下可视化的效果。

一、DFS,BFS的基本概念

摘自:明引树的广度优先遍历与深度优先遍历算法_明引的博客-CSDN博客_深度遍历和广度遍历算法1 树的广度优先搜索算法 广度优先搜索算法(Breadth First Search),又叫宽度优先搜索,或横向优先搜索。 是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。 如上图所示的二叉树,A 是第一个访问的,然后顺序是 B、C,然后再是 D、E、F、G。 那么,怎样才能来保证这个访问的顺序呢? 借助队列数据结构,由于队列是先进先出的顺序,因此可以先https://blog.csdn.net/lmingyin5/article/details/47282925

广度优先遍历算法,又叫宽度优先遍历,或横向优先遍历,是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。

深度优先遍历算法是遍历算法的一种。是沿着树的深度遍历树的节点。

当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。

如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。

摘自:小枫学IT https://blog.csdn.net/EngineerofAI/article/details/120590420广度优先搜索算法类似于二叉树的层序遍历,是一种分层的查找过程,每向前一步可能访问一批顶点,没有回退的情况,因此不是一个递归的算法。首先访问起始顶点v,接着由v出发,依存访问v的各个未访问过的邻接顶点w1,w2,…,wi,然后依次访问w1,w2,…,wi的所有未被访问过的邻接顶点;再从这些访问过的顶点出发,访问它们所有未被访问过的邻接顶点······依次类推,直到图中所有顶点都被访问过为止。

与广度优先搜索不同,深度优先搜索(Depth-First-Search,DFS)类似于树的先序遍历。过程:从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,直到所有顶点被全部走完,这种尽量往深处走的概念即是深度优先的概念。

二、DFS,BFS的C#实现

摘自: csdnBigBoy

代码可用,注释清晰全面,大家可以仔细阅读。

三、DFS,BFS的可视化实现

学生经常问,什么样的程序是好程序?最基本的就是:

(1)好读:程序要便于阅读;注释合理;格式化;

(2)好看:程序逻辑、思路清晰、模块与板块划分合理;命名规则一致;

(3)好用:运行正常;稳定第一、性能第二;

因此,程序的运行结果能及时被看到!程序可视化是重要的一种形式。

先看看效果:

上代码(改编自csdnBigBoy的代码 ):

using System;
using System.Text;
using System.Linq;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;

namespace DFSBFS
{
    public partial class Form1 : Form
    {
        TreeInfo TreeTotal = null;
        List<NodeInfo> PathResult = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Text = "深度优先搜索算法DFS,广度优先搜索算法BFS,可视化编程实例";
            button1.Text = "深度优先搜索算法 DFS"; button1.Cursor = Cursors.Hand;
            button2.Text = "广度优先搜索算法 BFS"; button2.Cursor = Cursors.Hand;
            panel1.Dock = DockStyle.Top; panel2.Dock = DockStyle.Fill;
            webBrowser1.Navigate("http://www.315soft.com");
        }

        private static TreeInfo TreeGrowth()
        {
            TreeInfo tree = new TreeInfo();
            tree.Append(new NodeInfo(1, new int[] { 3, 2, 4 }));
            tree.Append(new NodeInfo(2, new int[] { 1, 5, 8, 300 }));
            tree.Append(new NodeInfo(3, new int[] { 1, 7, 9, 100 }));
            tree.Append(new NodeInfo(4, new int[] { 1, 6, 10, 200 }));
            tree.Append(new NodeInfo(5, new int[] { 2 }));
            tree.Append(new NodeInfo(6, new int[] { 4 }));
            tree.Append(new NodeInfo(7, new int[] { 3 }));
            tree.Append(new NodeInfo(8, new int[] { 2 }));
            tree.Append(new NodeInfo(9, new int[] { 3, 400 }));
            tree.Append(new NodeInfo(10, new int[] { 4 }));
            tree.Append(new NodeInfo(100, new int[] { 3 }));
            tree.Append(new NodeInfo(200, new int[] { 4 }));
            tree.Append(new NodeInfo(300, new int[] { 2 }));
            tree.Append(new NodeInfo(400, new int[] { 9 }));
            return tree;
        }

        /// <summary>
        /// 深度优先搜索算法
        /// Deep First Search Algorithm
        /// </summary>
        /// <param name="Tree"></param>
        /// <param name="startNode"></param>
        private static List<NodeInfo> DFS(TreeInfo Tree, NodeInfo startNode)
        {
            // 详细注解请浏览原文
            // https://blog.csdn.net/CSDNBigBoy/article/details/80635220
            List<NodeInfo> path = new List<NodeInfo>();
            path.Add(startNode);
            List<NodeInfo> b = new List<NodeInfo>();
            b.Add(startNode);
            startNode.Visited = true;
            NodeInfo a = new NodeInfo();
            while (b.Count != 0)
            {
                List<NodeInfo> b_nbs = Tree.FindNeighbors(b[b.Count - 1]);
                a = b_nbs.FirstOrDefault(k => !k.Visited);
                while (a != null)
                {
                    b.Add(a);
                    path.Add(a);
                    a.Visited = true;
                    b_nbs = Tree.FindNeighbors(b[b.Count - 1]);
                    a = b_nbs.FirstOrDefault(k => !k.Visited);
                }
                if (a == null)
                {
                    b.Remove(b[b.Count - 1]);
                }
            }
            return path;
        }

        /// <summary>
        /// 广度优先搜索算法
        /// Breadth First Search Algorithm
        /// </summary>
        /// <param name="Tree"></param>
        /// <param name="startNode"></param>
        private static List<NodeInfo> BFS(TreeInfo Tree, NodeInfo startNode)
        {
            // 详细注解请浏览原文
            // https://blog.csdn.net/CSDNBigBoy/article/details/80635220
            List<NodeInfo> path = new List<NodeInfo>();
            path.Add(startNode);
            Queue qq = new Queue();
            qq.Enqueue(startNode);
            startNode.Visited = true;
            NodeInfo a = new NodeInfo();
            while (qq.Count != 0)
            {
                a = (NodeInfo)qq.Dequeue();
                List<NodeInfo> a_nbs = Tree.FindNeighbors(a);
                foreach (NodeInfo tmp in a_nbs.Where(k => !k.Visited).ToList())
                {
                    qq.Enqueue(tmp);
                    path.Add(tmp);
                    tmp.Visited = true;
                }
            }
            return path;
        }

        private string ShowPath()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
            sb.AppendLine("<html xmlns=\"http://www.w3.org/1999/xhtml\" >");
            sb.AppendLine("<head>");
            sb.AppendLine("<style>");
            sb.AppendLine(".ball1 { width:30px;height:30px;font-size:12px;line-height:30px;border:solid 1px #999999;background-color:#F0F0F0;text-align:center;border-radius:15px; }");
            sb.AppendLine(".ball2 { width:30px;height:30px;font-size:12px;line-height:30px;border:solid 1px #FF6701;background-color:#FA9A70;text-align:center;border-radius:15px; }");
            sb.AppendLine(".node { float:left;width:20px;height:20px;font-size:12px;line-height:20px;border:solid 1px #FF6701;background-color:#FAFAF0;text-align:center;border-radius:10px; }");
            sb.AppendLine(".arrow { float:left;width:20px;height:20px;font-size:12px;line-height:20px;border:solid 0px #FF6701;background-color:#FFFFFF;text-align:center; }");
            sb.AppendLine("</style>");
            sb.AppendLine("<script type=\"text/javascript\" src=\"" + Application.StartupPath.Replace(@"\", @"/") + "/jquery-3.6.0.min.js\"></script>");
            sb.AppendLine("<script type=\"text/javascript\" src=\"" + Application.StartupPath.Replace(@"\", @"/") + "/dfsbfs.js\"></script>");
            sb.AppendLine("</head>");
            sb.AppendLine("<body>");
            sb.AppendLine("<img src='https://img-blog.csdn.net/20180609184540410' width='400'><br>");
            sb.AppendLine(ShowInTable());
            sb.AppendLine("<br>");
            int k = 0;
            foreach (NodeInfo node in PathResult)
            {
                sb.AppendLine("<div class='node'>" + node.Id + "</div>");
                sb.AppendLine("<div class='arrow'>→</div>");
                if (k >= loop) break;
                k++;
            }
            sb.AppendLine("<script language=\"javascript\">");
            sb.AppendLine("$(document).ready(function() {");
            sb.AppendLine("CanvasCreate();");
            foreach(NodeInfo node in TreeTotal.Nodes)
            {
                for (int i = 0; i < node.Neighbors.Length; i++)
                {
                    sb.AppendLine("Connect(\"" + node.Id + "\", \""+ node.Neighbors[i] + "\");");
                }
            }
            sb.AppendLine("});");
            sb.AppendLine("</script>");
            sb.AppendLine("</body>");
            sb.AppendLine("</html>");
            return sb.ToString();
        }
        int loop = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            TreeTotal = TreeGrowth();
            PathResult = DFS(TreeTotal, TreeTotal.First());

            timer1.Interval = 1000;
            timer1.Enabled = true;
            loop = 0;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            TreeTotal = TreeGrowth();
            PathResult = BFS(TreeTotal, TreeTotal.First());
            timer1.Interval = 1000;
            timer1.Enabled = true;
            loop = 0;
        }
        public string ShowInTable()
        {
            int[,] matrix = new int[4, 9]
            {
                { 0,0,0,0,1,0,0,0,0 },
                { 0,3,0,0,2,0,0,4,0 },
                { 7,9,100,5,8,300,6,10,200 },
                { 0,400,0,0,0,0,0,0,0 },
            };

            for(int i = 0; i < TreeTotal.Nodes.Count; i++)
            {
                TreeTotal.Nodes[i].Visited = false;
            }
            for (int i = 0; i <= loop; i++)
            {
                PathResult[i].Visited = true;
            }

            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<style>td { padding:10px; }</style>");
            sb.AppendLine("<table width='300' border='1' bordercolor='#EEEEEE' style='border-collapse:collapse;'>");
            for (int y = 0; y < 4; y++)
            {
                sb.AppendLine("<tr>");
                for (int x = 0; x < 9; x++)
                {
                    int nk = matrix[y, x];
                    if (nk >= 100) nk = 10 + nk / 100;
                    if (nk == 0)
                    {
                        sb.Append("<td></td>");
                    }
                    else if (TreeTotal.Nodes[nk - 1].Visited == true)
                    {
                        sb.Append("<td><div class='ball2'>" + TreeTotal.Nodes[nk - 1].Id + "</div></td>");
                    }
                    else
                    {
                        sb.Append("<td><div class='ball1'>" + TreeTotal.Nodes[nk - 1].Id + "</div></td>");
                    }
                }
                sb.AppendLine("</tr>");
            }
            sb.AppendLine("</table>");
            return sb.ToString();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (loop < PathResult.Count)
            {
                webBrowser1.DocumentText = ShowPath();
                loop++;
                return;
            }
            loop = 0;
        }
    }

    /// <summary>
    /// 树
    /// </summary>
    public class TreeInfo
    {
        /// <summary>
        /// 所有节点
        /// </summary>
        public List<NodeInfo> Nodes { get; set; } = new List<NodeInfo>();
        /// <summary>
        /// 新增节点
        /// </summary>
        /// <param name="node"></param>
        public void Append(NodeInfo node)
        {
            Nodes.Add(node);
        }
        /// <summary>
        /// 第一个节点
        /// </summary>
        /// <returns></returns>
        public NodeInfo First()
        {
            return Nodes[0];
        }
        /// <summary>
        /// 搜索指定节点的邻居(邻接节点)
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public List<NodeInfo> FindNeighbors(NodeInfo node)
        {
            List<NodeInfo> list = new List<NodeInfo>();
            foreach (int nx in node.Neighbors)
            {
                list.Add(Nodes.FirstOrDefault(k => k.Id == nx));
            }
            return list;
        }
    }
    /// <summary>
    /// 节点信息
    /// 来自:https://blog.csdn.net/CSDNBigBoy/article/details/80635220
    /// </summary>
    public class NodeInfo
    {
        /// <summary>
        /// 节点的id
        /// </summary>
        public int Id { get; set; } = 0;
        /// <summary>
        /// 是否被遍历过的标记,默认false表示没有被遍历过
        /// </summary>
        public bool Visited { get; set; } = false;
        /// <summary>
        /// 用于存储该元素的临接元素的id
        /// </summary>
        public int[] Neighbors { get; set; } = null;
        /// <summary>
        /// 构造函数
        /// </summary>
        public NodeInfo() { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id"></param>
        /// <param name="neighbors"></param>
        public NodeInfo(int id, int[] neighbors)
        {
            Id = id;
            Neighbors = neighbors;
        }
    }
}

有动图,效果就是不一样!

需要两个 js 文件,一个是 jQuery ,自己去下载吧。

另外一个画(绘制)树结构的源代码 dfsbfs.js。

在工程包内,下载解压即可。

 ——————————————————————

POWER BY 315SOFT.COM &
TRUFFER.CN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1362729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp选择android非图片文件的方案踩坑记录

这个简单的问题我遇到下面6大坑&#xff0c;原始需求是选择app如android的excel然后读取到页面并上传表格数据json 先看看效果 uniapp 选择app excel文件读取 1.uniapp自带不支持 uniapp选择图片和视频非常方便自带已经支持可以直接上传和读取 但是选择word excel的时候就出现…

红外传感器(含代码注释)

一.引言 红外传感器是一种能够检测和测量红外光的传感器。由于红外光的特性&#xff0c;红外传感器在许多领域中得到了广泛的应用&#xff0c;如军事、航空航天、医疗、环保、工业控制等。本文将详细介绍红外传感器的原理、应用以及未来发展趋势。 二.红外传感器的工作原理 红外…

Vue3-41-组件- 动态组件 component 标签 和 is 属性 的使用

说明 <component> 标签 有一个 is 属性&#xff0c; 可以给这个 is属性 赋值为一个 组件对象&#xff0c; 这样这个<component> 标签就可以渲染指定的组件对象了。 使用案例 本案例中会 准备两个简单的组件&#xff0c; 在 App.vue 中导入这两个组件&#xff0c;并…

Thonny开发ESP32点灯

简介 ESP32是一款功能强大的低功耗微控制器&#xff0c;由乐鑫&#xff08;Espressif&#xff09;公司开发。它集成了Wi-Fi和蓝牙功能&#xff0c;适用于各种物联网应用。Thonny是一款基于Python的开源集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为MicroPython设计…

SpringBoot学习(六)-SpringBoot整合Shiro

12、Shiro 12.1概述 12.1.1简介 Apache Shiro是一个强大且易用的Java安全框架 可以完成身份验证、授权、密码和会话管理 Shiro 不仅可以用在 JavaSE 环境中&#xff0c;也可以用在 JavaEE 环境中 官网&#xff1a; http://shiro.apache.org/ 12.1.2 功能 Authentication…

【Leetcode】230. 二叉搜索树中第K小的元素

一、题目 1、题目描述 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例1: 输入:root = [3,1,4,null,2], k = 1 输出:1示例2: 输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3提示: 树中…

Supershell反溯源配置

简介 项目地址&#xff1a;https://github.com/tdragon6/Supershell Supershell是一个集成了reverse_ssh服务的WEB管理平台&#xff0c;使用docker一键部署&#xff08;快速构建&#xff09;&#xff0c;支持团队协作进行C2远程控制&#xff0c;通过在目标主机上建立反向SSH隧…

1389 蓝桥杯 二分查找数组元素 简单

1389 蓝桥杯 二分查找数组元素 简单 //C风格解法1&#xff0c;lower_bound(),通过率100% //利用二分查找的方法在有序的数组中查找&#xff0c;左闭右开 #include <bits/stdc.h> using namespace std;int main(){int data[200];for(int i 0 ; i < 200 ; i) data[i] …

Android 15即将到来,或将推出5大新功能特性

Android15 OneUI电池优化 三星最近完成了对其所有设备的稳定版 One UI 6.0 更新的推出&#xff0c;引起了用户的极大兴奋。据新出现的互联网统计数据显示&#xff0c;即将发布的基于 Android 15 的 One UI 7 将通过优化电池和功耗来重新定义用户体验&#xff0c;这是一项具有突…

听GPT 讲Rust源代码--compiler(19)

File: rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs 该文件&#xff08;rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs&#xff09;是Rust编译器针对MIPS架构上的Linux系统的目标描述文件。它的作用是定义了在这个目标上编译时的一些配置…

商品砍价系统设计原理与实践:技术解析与注意事项

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Java序列化篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、什么是java序列化,如何实现java序列化?二、保存(持久化)对象及其状态到内存或者磁盘三、序列化对象以字节数组保持-静态成员不保存四、序列化用户远程对象传输前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…

第16课 播放rtsp流

在现实生活中有许多rtsp摄像头&#xff0c;这些摄像头如果能充分利用起来可以生成很多有趣、有用的应用&#xff1a;比如户外互动大屏等。在第4课&#xff0c;我们实现了一个播放器&#xff0c;当时来用它播放rtmp流和mp4时它好象工作的很好。这节课我们就用它来播放rtsp流试试…

物联网产品中,终端、网关、协议、PaaS、SaaS之间的关系

在互联网产品中&#xff0c;经常提到的终端、网关、协议、PaaS、SaaS之间&#xff0c;到底有什么关系呢&#xff1f; 一、基本概念 在百度/其他地方搜集的信息中&#xff0c;对于终端、网关、协议、PaaS、SaaS的解释各有不同&#xff0c;整理如下&#xff1a; 终端&#xff1…

CMU15-445-Spring-2023-Project #1 - Buffer Pool

前置知识&#xff0c;参考上一篇博客&#xff1a;CMU15-445-Spring-2023-Project #1 - 前置知识&#xff08;lec01-06&#xff09; 在存储管理器中实现缓冲池。缓冲池负责将物理页从主内存来回移动到磁盘。它允许 DBMS 支持大于系统可用内存量的数据库。缓冲池的操作对系统中的…

【书生·浦语大模型实战营01】《书生·浦语大模型全链路开源体系》

《书生浦语大模型全链路开源体系》 1. 大模型成为热门关键词 LLM发展时间轴 2. 书生浦语全链条开源开放体系 微调&#xff1a;XTuner 支持全参数微调支持LoRA等低成本微调 评测&#xff1a;OpenCompass 全方位评测&#xff0c;性能可复现80套评测集&#xff0c; 40万道题目…

【大数据】Zookeeper 数据写入与分布式锁

Zookeeper 数据写入与分布式锁 1.数据是怎么写入的2.基于 Zookeeper 实现分布式锁 1.数据是怎么写入的 无论是 Zookeeper 自带的客户端 zkCli.sh&#xff0c;还是使用 Python&#xff08;或者其它语言&#xff09;实现的客户端&#xff0c;本质上都是连接至集群&#xff0c;然…

Linux 上 Nginx 配置访问 web 服务器及配置 https 访问配置过程记录

目录 一、前言说明二、配置思路三、开始修改配置四、结尾 一、前言说明 最近自己搭建了个 Blog 网站&#xff0c;想把网站部署到服务器上面&#xff0c;本文记录一下搭建过程中 Nginx 配置请求转发的过程。 二、配置思路 web项目已经在服务器上面运行起来了&#xff0c;运行的端…

Qt pro文件

1. 项目通常结构 2.pri文件 pri文件可定义通用的宏&#xff0c;例如创建一个COMMON.pri文件内容为 COMMON_PATH D:\MyData 然后其它pri或者pro文件如APPTemplate.pro文件中通过添加include(Common.pri) &#xff0c;QtCreator就会自动在项目结构树里面创建对应的节点 3.变量…

gitlab 配置 二

一 环境说明 群晖Nas DS418DELL XPS serverGitlab ce 二 需要实现的功能 外网可以访问&#xff0c;gitlab使用https的方式访问。wiki issue 等都可以上传图片和附件。 三 操作步骤 因为群晖上有证书&#xff0c;并且由群晖做转发功能。因此证书上&#xff0c;采用群晖的证书…