グラフの簡単な実装

基本的な紹介

  1. 多対多の関係を表現する必要がある場合は、グラフを使用する必要があります
  2. グラフを表現する方法は2つあります。2次元配列表現(隣接行列)、リンクリスト表現(隣接リスト)です。
  3. グラフトラバーサルモード:深さ優先トラバーサル;幅優先トラバーサル

深さ優先探索

ここに画像の説明を挿入します

幅優先探索

ここに画像の説明を挿入します

2つのトラバーサル方法の比較

ここに画像の説明を挿入します

コード

package graph;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 
 * @Description  图
 * @author ningqian		QQ:2587658527
 * @version 
 * @date 2021年3月18日下午3:56:28
 */
public class Graph {
    
    

	private ArrayList<String> vertexList ;//顶点列表,存放的是String类型的值
	private int[][] edges;//存储图对应的邻接矩阵
	private int numOfEdges;  //总共有多少条边
	private boolean[] isVisit;//记录每个顶点是否被访问过(其实完全可以将顶点设为一个类的对象,将这个值作为对象的一个属性存在)
	private ArrayList<Integer> list ;
	
	public static void main(String[] args) {
    
    
		// 构建图
		Graph graph1 = new Graph(5);
		Graph graph2 = new Graph(8);
		String[] strList = {
    
     "A", "B", "C", "D", "E" };
		String[] strList2 = {
    
     "1", "2", "3", "4", "5", "6", "7", "8" };
		// 添加节点
//		for(String s:strList) {
    
    
//			graph1.addVertex(s);
//		}
		// 添加节点
		for (String s : strList2) {
    
    
			graph2.addVertex(s);
		}
		// 构建边
//		graph1.addEdge(0, 1, 1);
//		graph1.addEdge(0, 2, 1);
//		graph1.addEdge(1, 2, 1);
//		graph1.addEdge(1, 3, 1);
//		graph1.addEdge(1, 4, 1);

		// 构建另一个边

		graph2.addEdge(0, 1, 1);
		graph2.addEdge(0, 2, 1);
		graph2.addEdge(1, 3, 1);
		graph2.addEdge(1, 4, 1);
		graph2.addEdge(2, 5, 1);
		graph2.addEdge(2, 6, 1);
		graph2.addEdge(3, 7, 1);
		graph2.addEdge(4, 7, 1);
		graph2.addEdge(5, 6, 1);

		// 显示图
		// graph1.showGraph();
		graph2.showGraph();
		// 深度优先遍历
		// graph1.dfs(0);
		// graph2.dfs(0);
		// 广度优先遍历
		// graph1.bfs(0);
		graph2.bfs(0);

	}
	//构造器
	public Graph() {
    
    
		super();
	}

	public Graph(int n) {
    
     //创建一个n个顶点的图
		super();
		vertexList = new ArrayList<String>(n);//初始化列表的容量
		edges = new int[n][n]; //创建一个n*n的邻接矩阵
		numOfEdges = 0;  //边的数量首先是0
		isVisit = new boolean[n];
		list = new ArrayList<Integer>(n);
	}
	//添加顶点
	public void addVertex(String vertex) {
    
    
		vertexList.add(vertex);
	}
	//添加定点m和定点n之间的边,w为边的权重
	public void addEdge(int m,int n,int w) {
    
    
		edges[m][n] = w;
		edges[n][m] = w;
		//将总边数加一
		numOfEdges++;
	}
	//返回顶点个数
	public int numOfVertex() {
    
    
		return vertexList.size();
	}
	//返回边的个数
	public int numOfEdge() {
    
    
		return numOfEdges;
	}
	//返回索引i对应的定点
	public String getVertex(int i) {
    
    
		return vertexList.get(i);
	}
	//返回顶点m和顶点n之间的边的权重
	public int getWeight(int m,int n) {
    
    
		return edges[m][n];
	}
	//遍历输出邻接矩阵
	public void showGraph() {
    
    
		for(int[] line:edges) {
    
    
			System.out.println(Arrays.toString(line));
		}
	}
	//设置访问标识
	public void setIsVisit(int i,boolean bool) {
    
    
		isVisit[i] = bool;
	}
	//图的深度优先遍历树DFS(depth first search)
	public void dfs(int index) {
    
    
		String s = getVertex(index);
		setIsVisit(index,true);
		System.out.print(s+"->");
		for(int i = 0;i<numOfVertex();i++) {
    
    
			if(edges[index][i]==1&&isVisit[i]==false) {
    
    
				dfs(i);
			}
		}
	}
	//图的广度优先遍历BFS
	public void bfs(int index) {
    
    
		if(index==0) {
    
    
			setIsVisit(index,true);
			System.out.print(getVertex(index)+"->");
		}
		String s = getVertex(index);
		for(int j=0;j<numOfVertex();j++) {
    
    
			if(edges[index][j]==1&&isVisit[j]==false) {
    
    
				setIsVisit(j,true);
				list.add(j);
				System.out.print(getVertex(j)+"->");
			}
		}
		if(list.size()!=0) {
    
    
			//移除队列
			int i =list.remove(0);
			bfs(i);
		}
		else {
    
    
			return;
		}
	}
	
	
	
}

おすすめ

転載: blog.csdn.net/m0_38143506/article/details/114988287