一、基本知识
二、快速入门
①创建
package com.ws.数据结构.图.创建;
import java.util.ArrayList;
import java.util.Arrays;
public class Grapn {
private ArrayList<String> dingTextList;//存储顶点集合
private int[][] edges;//存储图对应的邻接矩阵
private int numBian;//边的数目
public static void main(String[] args) {
//测试图创建
int n=5;//节点的个数
String v1[] = {"A","B","C","D","E"};
//创建图
Grapn grapn = new Grapn(n);
//循环添加顶点
for (String a:v1){
grapn.insertDing(a);
}
//添加边
grapn.insertBian(0,1,1);//A-B
grapn.insertBian(0,2,1);
grapn.insertBian(1,2,1);
grapn.insertBian(1,3,1);
grapn.insertBian(1,4,1);
//显示临界就诊
grapn.printfTu();
}
//构造器
public Grapn(int n){
//初始化矩阵和顶点集合
edges=new int[n][n];//初始化邻接矩阵
dingTextList=new ArrayList<>(n);//初始化顶点集合
numBian=0;//初始化边个数
}
//插入节点
public void insertDing(String ding){
dingTextList.add(ding);
}
/**
* 添加边
* @param v1 节点下标
* @param v2 节点下标
* @param bian 边(二维数组值 1连)
*/
public void insertBian(int v1,int v2,int bian){
edges[v1][v2]=bian;
edges[v2][v1]=bian;
numBian++;//边数目增加
}
//图中常用的额方法
//返回节点的个数
public int getNumVer(){
return dingTextList.size();
}
//返回边的个数
public int getNumBian(){
return numBian;
}
//返回节点i对应的数据
public String getValueByIndex(int i){
return dingTextList.get(i);
}
//返回v1和v2的权值
public int getBian(int v1,int v2){
return edges[v1][v2];
}
//显示图
public void printfTu(){
for (int[] link:edges){
System.out.println(Arrays.toString(link));
}
}
}
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
②深度优先遍历
package com.ws.数据结构.图.遍历.深度优先DFS;
import java.util.ArrayList;
import java.util.Arrays;
public class Grapn {
private ArrayList<String> dingTextList;//存储顶点集合
private int[][] edges;//存储图对应的邻接矩阵
private int numBian;//边的数目
//定义数组,标记某个节点是否被访问过
private boolean[] ifFangWen;
public static void main(String[] args) {
//测试图创建
int n=5;//节点的个数
String v1[] = {"A","B","C","D","E"};
//创建图
Grapn grapn = new Grapn(n);
//循环添加顶点
for (String a:v1){
grapn.insertDing(a);
}
//添加边
grapn.insertBian(0,1,1);//A-B
grapn.insertBian(0,2,1);
grapn.insertBian(1,2,1);
grapn.insertBian(1,3,1);
grapn.insertBian(1,4,1);
//显示临界就诊
grapn.printfTu();
//深度遍历测试
System.out.println("深度优先遍历");
grapn.DFS();
}
//构造器
public Grapn(int n){
//初始化矩阵和顶点集合
edges=new int[n][n];//初始化邻接矩阵
dingTextList=new ArrayList<>(n);//初始化顶点集合
numBian=0;//初始化边个数
ifFangWen=new boolean[n];//记录某个节点是否被访问
}
//插入节点
public void insertDing(String ding){
dingTextList.add(ding);
}
/**
* 添加边
* @param v1 节点下标
* @param v2 节点下标
* @param bian 边(二维数组值 1连)
*/
public void insertBian(int v1,int v2,int bian){
edges[v1][v2]=bian;
edges[v2][v1]=bian;
numBian++;//边数目增加
}
//图中常用的额方法
//返回节点的个数
public int getNumVer(){
return dingTextList.size();
}
//返回边的个数
public int getNumBian(){
return numBian;
}
//返回节点i对应的数据
public String getValueByIndex(int i){
return dingTextList.get(i);
}
//返回v1和v2的权值
public int getBian(int v1,int v2){
return edges[v1][v2];
}
//显示图
public void printfTu(){
for (int[] link:edges){
System.out.println(Arrays.toString(link));
}
}
/**
* 得到第一个临接节点的下标 开头
* @param index 当前节点的下标
* @return 如果存在就返回对应下标 y
*/
public int getLinBiao(int index){
for (int i=0;i<dingTextList.size();i++){
if (edges[index][i]>0) {
return i;
}
}
return -1;
}
/**
* 获取下一个临接节点
* @param x 前一个临接节点的x坐标
* @param y y
* @return 下一个邻接节点的y坐标
*/
public int getNextBiao(int x,int y){
for (int j=y+1;j<dingTextList.size();j++){
if(edges[x][j]>0){
return j;
}
}
return -1;
}
/**
* 深度优先遍历
* @param ifFangWen 是否访问过标志
* @param i 第一次是0 路径节点
*/
private void DFS(boolean[] ifFangWen,int i){
//输出访问过的节点
System.out.print(getValueByIndex(i)+"->");//返回相应节点的数据
//将该节点设置为已经访问
ifFangWen[i]=true;
//查找i的邻接节点
int linjie=getLinBiao(i);// A b c ...
//递归找邻接节点
while (linjie!=-1){
if (!ifFangWen[i]){
//没有被访问过,就递归找访问过的 输出路径
DFS(ifFangWen,i);
}
//节点已经被访问过就查找
linjie=getNextBiao(i,linjie);// A-B A-C
}
}
/**
* 重载,对多个起点(多个行)进行路径查找
*/
public void DFS(){
//遍历所有行(节点)
for (int i=0;i<getNumBian();i++){
if (!ifFangWen[i]){
DFS(ifFangWen,i);
}
}
}
}
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
深度优先遍历
A->B->C->D->E->
③广度优先遍历
package com.ws.数据结构.图.遍历.广度优先;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
public class Grapn {
private ArrayList<String> dingTextList;//存储顶点集合
private int[][] edges;//存储图对应的邻接矩阵
private int numBian;//边的数目
//定义数组,标记某个节点是否被访问过
private boolean[] ifFangWen;
public static void main(String[] args) {
//测试图创建
int n=5;//节点的个数
String v1[] = {"A","B","C","D","E"};
//创建图
Grapn grapn = new Grapn(n);
//循环添加顶点
for (String a:v1){
grapn.insertDing(a);
}
//添加边
grapn.insertBian(0,1,1);//A-B
grapn.insertBian(0,2,1);
grapn.insertBian(1,2,1);
grapn.insertBian(1,3,1);
grapn.insertBian(1,4,1);
//显示临界就诊
grapn.printfTu();
//深度遍历测试
//System.out.println("深度优先遍历");
//grapn.DFS();
//广度优先遍历
System.out.println();
System.out.println("广度优先遍历");
grapn.guangDFS();
}
//构造器
public Grapn(int n){
//初始化矩阵和顶点集合
edges=new int[n][n];//初始化邻接矩阵
dingTextList=new ArrayList<>(n);//初始化顶点集合
numBian=0;//初始化边个数
ifFangWen=new boolean[n];//记录某个节点是否被访问
}
//插入节点
public void insertDing(String ding){
dingTextList.add(ding);
}
/**
* 添加边
* @param v1 节点下标
* @param v2 节点下标
* @param bian 边(二维数组值 1连)
*/
public void insertBian(int v1,int v2,int bian){
edges[v1][v2]=bian;
edges[v2][v1]=bian;
numBian++;//边数目增加
}
//图中常用的额方法
//返回节点的个数
public int getNumVer(){
return dingTextList.size();
}
//返回边的个数
public int getNumBian(){
return numBian;
}
//返回节点i对应的数据
public String getValueByIndex(int i){
return dingTextList.get(i);
}
//返回v1和v2的权值
public int getBian(int v1,int v2){
return edges[v1][v2];
}
//显示图
public void printfTu(){
for (int[] link:edges){
System.out.println(Arrays.toString(link));
}
}
/**
* 得到第一个临接节点的下标 开头
* @param index 当前节点的下标
* @return 如果存在就返回对应下标 y
*/
public int getLinBiao(int index){
for (int i=0;i<dingTextList.size();i++){
if (edges[index][i]>0) {
return i;
}
}
return -1;
}
/**
* 获取下一个临接节点
* @param x 前一个临接节点的x坐标
* @param y y
* @return 下一个邻接节点的y坐标
*/
public int getNextBiao(int x,int y){
for (int j=y+1;j<dingTextList.size();j++){
if(edges[x][j]>0){
return j;
}
}
return -1;
}
/**
* 深度优先遍历
* @param ifFangWen 是否访问过标志
* @param i 第一次是0 路径节点
*/
private void DFS(boolean[] ifFangWen,int i){
//输出访问过的节点
System.out.print(getValueByIndex(i)+"->");//返回相应节点的数据
//将该节点设置为已经访问
ifFangWen[i]=true;
//查找i的邻接节点
int linjie=getLinBiao(i);// B A
//递归找邻接节点
while (linjie!=-1){
if (!ifFangWen[i]){
//没有被访问过,就递归找访问过的 输出路径
DFS(ifFangWen,i);
}
//节点已经被访问过就查找
linjie=getNextBiao(i,linjie);// A-B A-C
}
}
/**
* 重载,对多个起点(多个行)进行路径查找
*/
public void DFS(){
//遍历所有行(节点)
for (int i=0;i<getNumBian();i++){
if (!ifFangWen[i]){
DFS(ifFangWen,i);
}
}
}
//广度优先遍历
private void guangDFS(boolean[] ifFangWen,int i){
int u;//队列头节点下标 节点
int lin;//临接节点的下标
//队列 广度遍历节点访问顺序记录
LinkedList<Integer> queue = new LinkedList<>();
//访问节点
System.out.print(getValueByIndex(i)+"->");
//标记成已访问
ifFangWen[i]=true;
//将节点加入序列
queue.addLast(i);
while (!queue.isEmpty()){
//取出队列的头节点下标
u=queue.removeFirst();
//得到第一个临接节点得到下标
lin=getLinBiao(u);
while (lin!=-1){
//找到
//是否访问过
if (!ifFangWen[lin]){
//输出
System.out.print(getValueByIndex(lin)+"->");
//标记已经访问
ifFangWen[lin]=true;
//入队
queue.addLast(lin);
}
//访问过 还以当前节点,继续访问
lin=getNextBiao(u,lin);
}
}
}
//广度优先遍历 所有的节点
public void guangDFS(){
for (int i=0;i<getNumBian();i++){
if (!ifFangWen[i]){
guangDFS(ifFangWen,i);
}
}
}
}
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
广度优先遍历
A->B->C->D->E->