1.图的表示方法

图:G=(V,E),V代表节点,E代表边。

图有两种表示方法:邻接链表和邻接矩阵

邻接链表因为在表示稀疏图(边的条数|E|远远小于|V|²的图)时非常紧凑而成为通常的选择。

如果需要快速判断任意两个节点之间是否有边相连,可能也需要使用邻接矩阵表示法。

邻接链表表示法的鲁棒性很高,可以对其进行简单修改来支持许多其他的图变种。

邻接链表的一个潜在缺陷是无法快速判断一条边是否是图中地一条边。邻接矩阵则克服了这个缺陷,但付出的代价是更大的存储空间消耗。

——摘自《算法导论》

(1)无向图的两种表示

(2)有向图的两种表示

2.图的搜索算法

图的搜索算法即:广度优先搜索和深度优先搜索

相信这两种搜索算法的基本概念根据名字就可窥得一二,不多说,直接上例子。

如上有向图,创建三个类:

  • 点Vertex:包括点的名称(String)和访问标志(boolean)。
  • 边Edge:包括前驱点(Vertex)和后继点(Vertex)。
  • 图Graph:包括点集合(ArrayList<Vertex>)和边集合(ArrayList<Edge>)。

以下是构建好的图信息以及点遍历结果。

以下是Java源码。BFS辅以队列以非递归方法完成,DFS以递归方法完成。注释得很详细,我就不多解释了@(^<>^)@。

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue; class Graph{
ArrayList<Vertex> vertexs=new ArrayList<Vertex>();
ArrayList<Edge> edges=new ArrayList<Edge>(); public void addVertex(Vertex vertex) {
vertexs.add(vertex);
} public void addEdge(Edge edge) {
edges.add(edge);
}
} //顶点类
class Vertex{
String name;
boolean visited=false; //标记该点是否被查看-广度优先专用
boolean visited2=false; //标记该点是否被查看-深度优先专用 public Vertex(String name) {
this.name=name;
} @Override
public String toString() {
return "[" + name + "]";
}
}
//边类 有向图
class Edge{
Vertex start;
Vertex end; public Edge(Vertex start,Vertex end) {
this.start=start;
this.end=end;
} @Override
public String toString() {
return "(" + start + "," + end + ")";
}
} public class SearchGraph {
//广度优先 非递归
static void BFS(Graph graph) {
ArrayList<Vertex> vertexs=graph.vertexs;
ArrayList<Edge> edges=graph.edges;
Queue<Vertex> queue = new LinkedList<Vertex>(); //创建队列 queue.add(vertexs.get(0)); //顶节点放入队列
vertexs.get(0).visited=true; //顶节点设为已阅
System.out.print(vertexs.get(0)); while(!queue.isEmpty()) {
Vertex vertex=queue.remove();
for(Edge edge:edges) {
if(edge.start.equals(vertex)&&edge.end.visited==false) {
queue.add(edge.end);
edge.end.visited=true;
System.out.print(edge.end);
}
}
} } //深度优先 递归
static void DFS(Graph graph,Vertex vertex) { //参数:图、点信息
System.out.print(vertex);
vertex.visited2=true; for(Edge edge:graph.edges) {
if(edge.start.equals(vertex)&&edge.end.visited2==false) {
DFS(graph,edge.end);
}
}
} public static void main(String[] args) {
// TODO Auto-generated method stub //构造有向图
Graph graph=new Graph();
Vertex v0=new Vertex("v0");
Vertex v1=new Vertex("v1");
Vertex v2=new Vertex("v2");
Vertex v3=new Vertex("v3");
Vertex v4=new Vertex("v4");
Vertex v5=new Vertex("v5");
Vertex v6=new Vertex("v6");
graph.addVertex(v0);
graph.addVertex(v1);
graph.addVertex(v2);
graph.addVertex(v3);
graph.addVertex(v4);
graph.addVertex(v5);
graph.addVertex(v6);
Edge e0=new Edge(v0,v1);
Edge e1=new Edge(v0,v2);
Edge e2=new Edge(v0,v3);
Edge e3=new Edge(v1,v4);
Edge e4=new Edge(v1,v5);
Edge e5=new Edge(v2,v4);
Edge e6=new Edge(v3,v5);
Edge e7=new Edge(v4,v6);
Edge e8=new Edge(v5,v6);
graph.addEdge(e0);
graph.addEdge(e1);
graph.addEdge(e2);
graph.addEdge(e3);
graph.addEdge(e4);
graph.addEdge(e5);
graph.addEdge(e6);
graph.addEdge(e7);
graph.addEdge(e8);
//构造有向图 //测试图创建结果
ArrayList<Vertex> vertexs=graph.vertexs;
ArrayList<Edge> edges=graph.edges;
Iterator iVertex=vertexs.iterator();
Iterator iEdge=edges.iterator();
System.out.println("点集合:");
while(iVertex.hasNext()) {
System.out.print(iVertex.next());
}
System.out.println();
System.out.println("边集合:");
while(iEdge.hasNext()) {
System.out.print(iEdge.next());
}
//测试图创建结果 //遍历
System.out.println("");
System.out.println("广度优先遍历:");
BFS(graph);
System.out.println("");
System.out.println("深度优先遍历:");
DFS(graph,v0);
//遍历
} }

图-图的表示、搜索算法及其Java实现的更多相关文章

  1. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  2. 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...

  3. 八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 简单插 ...

  4. 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...

  5. 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1.  向上归并排序的时候,需要一个暂存数组用来排序, 2.  将 ...

  6. 八大排序算法——快速排序(动图演示 思路分析 实例代码Java 复杂度分析)

    一.动图演示 二.思路分析 快速排序的思想就是,选一个数作为基数(这里我选的是第一个数),大于这个基数的放到右边,小于这个基数的放到左边,等于这个基数的数可以放到左边或右边,看自己习惯,这里我是放到了 ...

  7. 八大排序算法——插入排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 例如从小到大排序: 1.  从第二位开始遍历, 2.  当前数(第一趟是第二位数)与前面的数依次比较,如果前面的数大于当前数,则将这个数放在当前数的位置上,当前数的下标-1 ...

  8. 八大排序算法——冒泡排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 1.  相邻两个数两两相比,n[i]跟n[j+1]比,如果n[i]>n[j+1],则将连个数进行交换, 2.  j++, 重复以上步骤,第一趟结束后,最大数就会被确定 ...

  9. 八大排序算法——选择排序(动图演示 思路分析 实例代码Java 复杂度分析)

    一.动图演示 二.思路分析 1.  第一个跟后面的所有数相比,如果小于(或小于)第一个数的时候,暂存较小数的下标,第一趟结束后,将第一个数,与暂存的那个最小数进行交换,第一个数就是最小(或最大的数) ...

随机推荐

  1. Python pandas & numpy 笔记

    记性不好,多记录些常用的东西,真·持续更新中::先列出一些常用的网址: 参考了的 莫烦python pandas DOC numpy DOC matplotlib 常用 习惯上我们如此导入: impo ...

  2. 陈远波(java)--Git 入门

    本章节讲解思路:1.在Git hup官网注册一个Git账号:2.下载git bash管理工具  3.在git bash上绑定GitHup账号密码: 一:进入GitHup官网:https://githu ...

  3. 开通博客啦 Let‘s Go!

    入园两年半,在博客园学到很多知识.得到了很大帮助,今天终于开通博客啦,准备将自己所学到的有用知识分享给大家,共同学习共同进步.

  4. python第三十课--异常(else讲解)

    演示else语句和异常处理机制结合使用 try: print('try...') print(10/0) except: print('except...') else: print('else... ...

  5. 【洛谷P3410】拍照题解(最大权闭合子图总结)

    题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. 注意:带下属不是白带的 ...

  6. Opatching PSU in Oracle Database 11g Release 2 RAC on RHEL6

    Opatching PSU in Oracle Database 11g Release 2(11.2.0.4) RAC on RHEL6 1) 升级opatch工具 1.1) For GI home ...

  7. 3.7 AnsyncTask异步任务

    3.7 AnsyncTask异步任务. 1)为什么要用AsyncTask? 答: 我们可以用上述两种方法来完成我们的异步操作,加入要我们写的异步操作比较多,或者较为繁琐, 难道我们new Thread ...

  8. linux 的常用命令---------第十阶段

    虚拟机三种网络模式 相同模式下的各个虚拟机之间都可以通信----两台虚拟机若都是 nat模式 或 桥接模式 或 仅主机模式,则这两台虚拟机之间是可以通信的. 桥接模式: (配置桥接模式的虚拟机可作为独 ...

  9. git回答整理

    1.git常用命令 首先明确:git有工作区.暂存区.版本库,工作区是电脑里能看到的目录 创建仓库: git init newrepo,使用我们指定目录作为Git仓库(初始化后,会在newrepo目录 ...

  10. Python2.7-functools

    functools 模块,是一个高阶函数模块,很有用,尤其是 partial 函数(类似函数定义了默认参数)和装饰器属性更新函数.装饰器在实现的时候,被修饰后的函数其实已经是另外一个函数了(函数名等函 ...