目录
一、图的创建
1.邻接矩阵
2.邻接表
3.其他存储方式
二、图的遍历
1.深度优先DFS(使用递归)
2.广度优先BFS(使用队列)
3.DFS与BFS的比较
三、最短路径求解
1.迪杰斯特拉算法(Dijkstra)
2.弗洛伊德算法(Floyd)
3.Dijkstra与Floyd的比较
抛出问题:为什么会有图这种数据结构?
因为线性表表示的是一对一的关系,树表示了一对多的关系。当我们需要使用到多对多关系时,就需要使用图这种数据结构。
图的创建
1.邻接矩阵(二维数组表示)
图有N个顶点,邻接矩阵就用N*N的二维数组表示。matrix[i][j] 的值为顶点i到顶点j的权值。比较简单,直接上java代码写的邻接矩阵(核心代码如下:)
public class Graph2 {
ArrayList<Vertex> vertexList; //顶点加入到List集合
int[][] edgeMatrix; //初始化后都为0
int vertexNum; //顶点数量
int edgeNum; //边的数量
/**
* 插入顶点
* @param vertex
*/
public void insertVertex(Vertex vertex){
vertexList.add(vertex);
//this.vertexNum++;
}
/**\
* 添加边
* @param v1 第一个顶点的下标
* @param v2 第二个顶点的下标
* @param weight 边的权值
*/
public void insertEdge(int v1,int v2,int weight){
edgeMatrix[v1][v2] =weight;
edgeMatrix[v2][v1] =weight; //无向图就加上这一句
edgeNum++;
}
}
/**
* 顶点类
*/
class Vertex {
String vertexName;
public Vertex(String vertexName) {
this.vertexName = vertexName;
}
@Override
public String toString() {
return vertexName ;
}
}
2.邻接表(一维数组加链表)
这里有两种实现情况:(这里数组都用ArrayList实现)
- 使用顶点链接顶点的方式构建图,这种方法比较low,头结点后链接的每一条边都是新new的顶点结点,这样做会避免指针紊乱,但会占用很多额外的空间。
- 使用边(边是由两个顶点V1 V2构成的)的第二个顶点V2所在ArayList中的索引位置作为边对象构建图(这种方法好些、李春葆教材使用的方式)
2.1使用顶点链接顶点的方式构建图
package vertex;
import java.util.Scanner;
/**
* 数组加链表形式 数组是vertexList ,用ArrayList来代替
* 邻接链表使用顶点作为对象构建图
*/
public class CreateGraph3 {
/**
* 根据用户输入的string类型的顶点返回该顶点
* @param graph 图
* @param str 输入顶点名称
* @return返回一个顶点
*/
public Vertex1 getVertex(Graph1 graph,String str){
for(int i=0;i<graph.verNum;i++){
if(graph.vertexArray[i].verName.equals(str)){
return graph.vertexArray[i];
}
}
return null;
}
/**
* 根据用户输入的数据初始化一个图,以邻接表的形式构建!
* @param graph 生成的图
*/
public void initialGraph(Graph1 graph){
@SuppressWarnings