java数据结构与算法(十)——图

图的创建以及深度优先遍历和广度优先遍历

package graph;

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

public class Graph {

	private ArrayList<String> vertexList; // 用于存放顶点的集合
	private int[][] edges; // 存储图对应的邻接矩阵
	private int numOfEdges; // 存储边的数目
	private boolean[] isVisited; //用于判断节点是否被访问过
	
	
	public static void main(String[] args) {
		int n = 5;
		int n1 = 8;
		String[] vertex = { "A", "B", "C", "D", "E" };
		
		String[] vertex1 = { "1", "2", "3", "4", "5", "6", "7", "8" };
		
		Graph graph = new Graph(n);
		
		Graph graph1 = new Graph(n1);
		//循环添加顶点
		for (String v : vertex) {
			graph.insertVertex(v);
		}
		//添加边
		graph.insertEdges(0, 1, 1);
		graph.insertEdges(0, 2, 1);
		graph.insertEdges(1, 2, 1);
		graph.insertEdges(1, 3, 1);
		graph.insertEdges(1, 4, 1);

		graph.showGraph();
		
		//循环添加顶点
		for (String v : vertex1) {
			graph1.insertVertex(v);
		}
		//添加边
		graph1.insertEdges(0, 1, 1);
		graph1.insertEdges(0, 2, 1);
		graph1.insertEdges(1, 3, 1);
		graph1.insertEdges(1, 4, 1);
		graph1.insertEdges(3, 7, 1);
		graph1.insertEdges(4, 7, 1);
		graph1.insertEdges(2, 5, 1);
		graph1.insertEdges(2, 6, 1);
		graph1.insertEdges(5, 6, 1);

		graph1.showGraph();
		
		System.out.println("深度优先遍历");
		graph.dfs();
		System.out.println();
		System.out.println("广度优先遍历");
		graph.bfs();
		System.out.println();
		System.out.println("深度优先遍历");
		graph1.dfs();
		System.out.println();
		System.out.println("广度优先遍历");
		graph1.bfs();
		
		
	}

	
	//构造器
	public Graph(int n1){ //传进来顶点的数目
		
		vertexList = new ArrayList<String>(n1);
		edges = new int[n1][n1]; 
		numOfEdges = 0;
		
		
	}
	
	//创建顶点
	public void insertVertex(String vertex) {
		vertexList.add(vertex); //传进来顶点信息,然后加入到ArrayList中
	}
	
	//创建边
	/**
	 * 
	 * @param v1 顶点对应的下标,比如A对应0
	 * @param v2 顶点对应的下标,比如B对应1
	 * @param weight 顶点之间是否有连接
	 */
	public void insertEdges(int v1, int v2, int weight) {
		edges[v1][v2] = weight;
		edges[v2][v1] = weight;
		numOfEdges++; //统计边的数目
	}
	
	//图中常用的方法
	
	//1.返回节点的数目
	public int getNumOfVertex() {
		return vertexList.size();
	}
	
	//2.返回边的数目
	public int getNumOfEdges() {
		return numOfEdges;
	}
	
	//3.返回邻接矩阵
	public void showGraph() {
		for (int[] link : edges) {
			System.out.println(Arrays.toString(link));
		}
	}
	
	//4.返回节点i(下标)对应的顶点
	public String getVertex(int i) {
		return vertexList.get(i);
	}
	
	//5.返回两顶点之间的权值
	public int getWeight(int v1, int v2) {
		return edges[v1][v2];
	}

	
	
	//得到第一个邻接节点的下标w
	public int getFirstNeighbor(int i) { //传进来当前节点v的下标
		for (int j = 0; j < vertexList.size(); j++) { //遍历所有顶点的下标
			if (edges[i][j] > 0) { //大于0说明ij下标对应的节点存在一条边
				return j;
			}
		}
		return -1;
	}
	
	// 根据前一个邻接节点的下标获取下一个邻接节点
	public int getNextNeighbor(int i, int j) { //i是前一个邻接节点的下标,j是m的前一个节点
		for (int m = j + 1; m < vertexList.size(); m++) {
			if (edges[i][m] > 0) {
				return m;
			}
		}
		return -1;
	}
	
	
	//深度优先遍历算法
	//i是传进来的节点的下标
	public void dfs(boolean[] isvisited, int i) {
		//首先访问该节点并输出
		System.out.print(getVertex(i) + "->");
		//将该节点设置为已经访问
		isvisited[i] = true;
		//查找当前节点的第一个邻接节点
		int w = getFirstNeighbor(i);
		while (w != -1) { //说明存在w
			if (isvisited[w] == false) { //如果w未被访问过
				dfs(isvisited, w); //递归遍历
			}else { 
				//如果w被访问过,查找当前节点的下一个邻接节点
				w = getNextNeighbor(i, w);
			}
		}
		
	}

	public void dfs() {
		isVisited = new boolean[vertexList.size()];
		for (int j = 0; j < getNumOfVertex(); j++) {
			if (isVisited[j] == false) {
				dfs(isVisited, j);
			}
		}
	}
	
	
	
	//图的广度优先遍历算法
	public void bfs(boolean[] isvisited,int i) {
		int u; //队列头结点对应的下标
		int w; //邻接节点的下标
		LinkedList<Integer> queue = new LinkedList<>(); //队列,用于记录节点访问的顺序
		
		//访问节点
		System.out.print(getVertex(i) + "->");
		// 标记为已访问
		isvisited[i] = true;
		//加入队列
		queue.addLast(i);
		
		while (!queue.isEmpty()) {
			u = queue.removeFirst();
			//查找节点u的第一个邻接节点的下标w
			w = getFirstNeighbor(u);
			//w存在
			while (w != -1) {
				//没有访问过
				if (isvisited[w] == false) {
					//访问
					System.out.print(getVertex(w) + "->");
					//标记为已访问
					isvisited[w] = true;
					//加入队列
					queue.addLast(w);
				}
				//查找节点u的继w邻接点后的下一个邻接点w
				w = getNextNeighbor(u, w);
			}
		}
		
	}
	
	
	//重载bfs,遍历所有的节点
	public void bfs() {
		isVisited = new boolean[vertexList.size()];
		for (int i = 0; i < getNumOfVertex(); i++) {
			if (!isVisited[i]) {
				bfs(isVisited, i);
			}
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值