无向图(邻接表实现)DFS_AND_BFS
数据结构选择TreeSet的原因:通过自定义的Compare方法,保证了点元素的唯一性,有序性(方便检验);
传入Set和Map中的元素类似于C中的指针操作,即共享地址,改变其中一个中的元素,与之相关的都会被改变;
实现代码内容:
1.图的定义;
2.插入点;
3.插入边;
4.BFS;
5.DFS;
代码如下:
/**
* FileName: Graph
* Author: Jerry
* Date: 2020/2/8 10:33
* Description: 图
*/
package Graph_DFS_AND_BFS; import java.util.*; public class Graph { //点类
static class Vertex implements Comparable<Vertex> {
private int name;
private boolean isVisiable; Vertex(int name) {
this.name = name;
} @Override
public int compareTo(Vertex o) {
return this.name-o.name;
}
} //图定义的顶点表和邻接表
private TreeSet<Vertex> vertexSet = new TreeSet<Vertex>();
private TreeMap<Vertex, LinkedList<Vertex>> map = new TreeMap<Vertex, LinkedList<Vertex>>(); //返回定点表和邻接表
private TreeSet<Vertex> getVertexSet()
{
return vertexSet;
}
private TreeMap<Vertex,LinkedList<Vertex>> getMap(){
return map;
} //图的初始化
//主要是为了先深搜索和先广搜索不会干扰考虑
private void initial(){
TreeSet<Vertex> vertexSet = getVertexSet();
TreeMap<Vertex,LinkedList<Vertex>> treeMap = getMap();
for(Vertex vertex:vertexSet){
vertex.isVisiable=false;
}
for(Vertex vertex:treeMap.keySet()){
vertex.isVisiable=false;
}
}
//构造函数
public Graph(TreeSet<Vertex> vertexSet,TreeMap<Vertex,LinkedList<Vertex>> map){
this.vertexSet=vertexSet;
this.map=map;
initial();
} //图的元素扩充
//放入点
public void putVertex(Vertex vertex){
TreeSet<Vertex> vertexSet = getVertexSet();
TreeMap<Vertex,LinkedList<Vertex>> map = getMap();
if(vertexSet.contains(vertex)){
System.out.println("重复元素!输入无效!");
}
else{
vertex.isVisiable=false;
vertexSet.add(vertex);
LinkedList<Vertex> list = new LinkedList<Vertex>();
map.put(vertex,list);
}
}
//放入边
public void putEdge(Vertex vertex1,Vertex vertex2){
TreeSet<Vertex> vertexSet = getVertexSet();
TreeMap<Vertex,LinkedList<Vertex>> map = getMap();
//在这里默认通过构造函数传入的TreeSet,TreeMap没有错误
//对vertex1的分析
if(vertexSet.contains(vertex1)){
if(!map.get(vertex1).contains(vertex2)){
map.get(vertex1).add(vertex2);
}//if
}//if
else{
vertexSet.add(vertex1);
LinkedList<Vertex> list = new LinkedList<>();
list.add(vertex2);
map.put(vertex1,list);
}//else //对vertex2的分析
if(vertexSet.contains(vertex2)){
if(!map.get(vertex2).contains(vertex1)){
map.get(vertex2).add(vertex1);
}//if
}//if
else{
vertexSet.add(vertex2);
LinkedList<Vertex> list = new LinkedList<>();
list.add(vertex1);
map.put(vertex2,list);
}//else
} //以上为图的构造过程,元素添加 //以下为图的搜索,DFS和BFS,由于图的搜索确定进入点很关键,我们采用重载,两个同名方法(参数是否包含搜索起始点) private void visit(Vertex vertex){
System.out.println(vertex.name);
}
//图的先深搜索
//默认从name最小的点开始搜索
public void DFS(){
System.out.println("先深搜索为:");
TreeMap<Vertex,LinkedList<Vertex>> map = getMap();
Vertex vertex = map.firstKey();
DFS(vertex);//如果确定从第一个键开始搜索,DFS可以优化,这里不作说明
} //带有起始点的搜索
public void DFS(Vertex vertex){
TreeMap<Vertex,LinkedList<Vertex>> map = getMap();
//访问vertex的连通区域
if(!vertex.isVisiable){
visit(vertex);
vertex.isVisiable=true;
for(Vertex vertex1:map.get(vertex)){
if(!vertex1.isVisiable){
DFS(vertex1);
}//if
}//for
}//if
//处理其它非连通区域,这里效率不高,但也很没有办法,否则无法保证从任意点开始访问
for(Vertex vertex2:map.keySet()){
if(!vertex2.isVisiable){
DFS(vertex2);
}
}
} //先广搜索,从第一个节点开始搜索
//值得注意的一点是,Set和Map中传入的元素是共享的,即它们传入的是类似于C中的指针操作;
public void BFS(){
System.out.println("BFS搜索如下:");
initial();
TreeMap<Vertex,LinkedList<Vertex>> map = getMap();
TreeSet<Vertex> treeSet = getVertexSet();
Queue<Vertex> queue = new LinkedList<Vertex>();
int i=0;
for(Vertex vertex:treeSet){
if(!vertex.isVisiable){
vertex.isVisiable=true;
visit(vertex);
queue.add(vertex);
while(!queue.isEmpty()){
Vertex vertex1 = queue.poll();
for(Vertex vertex2:map.get(vertex1)){
if (!vertex2.isVisiable) {
visit(vertex2);
vertex2.isVisiable=true;
queue.add(vertex2);
}//if
}//for
}//while }
} } public static void main(String []args){
TreeSet<Vertex> vertexSet= new TreeSet<>();
Vertex vertex1 = new Vertex(1);
Vertex vertex2 = new Vertex(2);
Vertex vertex3 = new Vertex(3);
Vertex vertex4 = new Vertex(4);
Vertex vertex5 = new Vertex(5);
vertexSet.add(vertex1);
vertexSet.add(vertex2);
vertexSet.add(vertex3);
vertexSet.add(vertex4);
vertexSet.add(vertex5); LinkedList<Vertex> list1 = new LinkedList<Vertex>();
LinkedList<Vertex> list2 = new LinkedList<Vertex>();
LinkedList<Vertex> list3 = new LinkedList<>();
LinkedList<Vertex> list4 = new LinkedList<>();
LinkedList<Vertex> list5 = new LinkedList<>();
list1.add(vertex2);list1.add(vertex3);list1.add(vertex4);
list2.add(vertex1);list2.add(vertex4);
list3.add(vertex1);list3.add(vertex5);
list4.add(vertex1);list4.add(vertex2);list4.add(vertex5);
list5.add(vertex4);list5.add(vertex3);
TreeMap<Vertex,LinkedList<Vertex>> map = new TreeMap<Vertex, LinkedList<Vertex>>() ;
map.put(vertex1,list1);map.put(vertex2,list2);map.put(vertex3,list3);
map.put(vertex4,list4);map.put(vertex5,list5);
Graph graph = new Graph(vertexSet,map);
graph.DFS();
graph.BFS();
} }
无向图(邻接表实现)DFS_AND_BFS的更多相关文章
- 图论——图的邻接表实现——Java语言(完整demo)
1.图的简单实现方法——邻接矩阵 表示图的一种简单的方法是使用一个一维数组和一个二维数组,称为领接矩阵(adjacent matrix)表示法. 对于每条边(u,v),置A[u,v]等于true:否则 ...
- 数据结构Java版之邻接表实现图(十)
邻接表实现图,实际上是在一个数组里面存放链表,链表存放的是连接当前节点的其他节点. package mygraph; import java.util.ArrayList; import java.u ...
- Codeforces Round #554 (Div. 2) E Neko and Flashback (欧拉路径 邻接表实现(当前弧优化..))
就是一欧拉路径 贴出邻接表欧拉路径 CODE #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; ...
- hibernate之关于使用连接表实现多对一关联映射
[Hibernate]之关于使用连接表实现多对一关联映射 在我们项目使用中採用中间表最多的一般就是多对一,或者是多对多,当然一对一使用中间表也是能够的,可是这样的几率通常少之又少!所以这里重点介绍多对 ...
- DataStructure-链表实现指数非递减一元多项式的求和
// 2-链表实现多项式的求和.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> #inclu ...
- 行逻辑链接的顺序表实现稀疏矩阵的相乘(Java语言描述)
行逻辑链接,带行链接信息.程序有空指针BUG,至今未解决.还是C/C++适合描述算法数据结构.以后复杂的算法还是改用C/C++吧. 有BUG的代码,总有一天会换成没有BUG的. package 行逻辑 ...
- SpringSecurity结合数据库表实现权限认证
SpringSecurity结合数据表实现权限认证: 下面的案例是在SpringBoot框架实现的: 步骤一:准备数据库表 以下是五张表的脚本 ### 用户表 create table Sys_Use ...
- bootstrap table 父子表实现【无限级】菜单管理功能
bootstrap table 父子表实现[无限级]菜单管理功能 实现效果 前端代码 <%@ page language="java" import="java.u ...
- Mybatis 多表实现多对多查询、添加操作
Mybatis 多表实现多对多查询.添加操作 学习内容: 1. 多对多之添加操作 1.1.需求 1.2.数据库表(多对多数据库设计需要设计中间表) 1.3.类设计 1.4.Mapper 接口和 Map ...
- Mybatis 多表实现多对一查询、添加操作
Mybatis 多表实现多对一查询.添加操作 学习内容: 1. 多对一之添加操作 1.1.需求 1.2.数据库表(多对一或一对多,数据库外键都是设置在多的一方) 1.3.类设计 1.4.Mapper ...
随机推荐
- 如何解决在WordPress安装Redis插件时需要输入FTP问题?
用LAMP或者LNMP搭建Worepress的时候,安装主题或者插件时候,往往提示需要输入FTP服务端信息的问题,其实这是一个坑,可以完全避免的 我们只需在wp-config.php文件最后添加以下代 ...
- 完全理解Python 迭代对象、迭代器、生成器
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- 关于Python闭包的一切
任何把函数当做一等对象的语言,它的设计者都要面对一个问题:作为一等对象的函数在某个作用域中定义,但是可能会在其他作用域中调用,如何处理自由变量? 自由变量(free variable),未在局部作用域 ...
- Jaxb的优点与用法(bean转xml的插件,简化webservice接口的开发工作量)
一.jaxb是什么 JAXB是Java Architecture for XML Binding的缩写.可以将一个Java对象转变成为XML格式,反之亦然. 我们把对象与关系数据库之间的映射称 ...
- .Net Core gRPC 实战(二)
概述 gRPC 客户端必须使用与服务相同的连接级别安全性. 如调用服务时通道和服务的连接级别安全性不一致,gRPC 客户端就会抛出错误. gRPC 配置使用HTTP gRPC 客户端传输层安全性 ( ...
- go语言json技巧
go语言json技巧 本文总结了在项目中遇到的那些关于go语言JSON数据与结构体之间相互转换的问题及解决办法. 基本的序列化 首先我们来看一下Go语言中json.Marshal()(系列化)与jso ...
- GO学习-(35) Go实现日志收集系统4
Go实现日志收集系统4 到这一步,我的收集系统就已经完成很大一部分工作,我们重新看一下我们之前画的图: 我们已经完成前面的部分,剩下是要完成后半部分,将kafka中的数据扔到ElasticSear ...
- bat使用方法汇总
前言 由于日常科研工作中使用C/C++比较多,在进行大规模运行时涉及到的批量处理操作较多,遂将目前遇到的情况记录如下,以便查看: 1.for循环 最基本的for循环操作为在一些数中遍历,如下例子.se ...
- Echarts-2.2.7中统计出来的统计图保存为图片
今天在做一个图形报表,有个需求是要把展现的统计图保存为图片, 图形报表用的Echarts-2.2.7, 以前有用过 Echarts,记得echarts插件是可以帮助我们把统计图保存为图片的. 只是不记 ...
- 浅谈:Redis持久化机制(二)AOF篇
浅谈:Redis持久化机制(二)AOF篇 上一篇我们提及到了redis的默认持久化方式RDB,是一种通过存储快照数据方式持久化的机制,它在宕机后会丢失掉最后一次更新RDB文件后的数据,这也是由于它 ...