Java实现图的深度优先遍历和广度优先遍历,深度广度优先遍历详解

**

Java实现数据结构,邻接矩阵实现图,Java实现图的深度、广度优先遍历

目录:

  1. 前言
  2. 深度预先遍历 使用递归
  3. 广度优先遍历 使用循环

前言:
首先这里主要讲Java实现图的深度和广度优先遍历,邻接矩阵实现图。
深度优先和广度优先首先是不难,你之所以会来查找如何实现深度优先和广度优先,我觉得是你的深度广度的逻辑不懂,这里会告诉你深度广度的逻辑是什么。然后用代码于实现。
示例图片
Java实现图的深度优先遍历和广度优先遍历,深度广度优先遍历详解_第1张图片
**

深度优先

	深度优先顾名思义就是:深是遍历的原则(深就是长驱直入),比如我们从A开始寻找,只要找到A的下一个邻接结点(就是和A相连的结点)就可以,找到的是B,再从B开始找B的下一个邻接结点找到的是C,在从C开始找C的邻接结点,(找过的就不在找),没有找到。这时我们说A的深度优先遍历就结束了,再开始B的深度优先遍历。
	深度优先简单来说,就是,长驱直入,不管有几个邻接结点,找到一个就行,找不到就从下一个结点开始深度优先遍历。
	代码实现:
/**
 * 
 * @author 楠
 *
 */
//图
class graph{
	public ArrayList<String> vertex;//存储结点的字符串数组
	public int[][] edges;//邻接矩阵
	public int numOfEdge;//边的个数
	public boolean[] isVisited;//辅助遍历工具,用来判断一个结点是否被访问过
	//构造器
	public graph(int n) {//初始化图
		vertex=new ArrayList<String>(n);
		edges=new int[n][n];
		numOfEdge=0;
	}
	//深度优先遍历图
	public void dfs() {//对每一个结点都进行深度优先遍历
		isVisited=new boolean[vertex.size()];//初始化辅助工具,初始均为未被访问
		for(int i=0;i<vertex.size();i++) {
			if(isVisited[i]) {//被访问就跳过
				continue;
			}else {
				dfs(i);
			}
		}
	}
	private void dfs(int i) {//对结点i进行深度优先遍历
		System.out.print(getValueOfVertex(i)+"---");
		isVisited[i]=true;
		int n=getFirst(i);//查找i的邻接结点
		if(n!=-1) {//找到了
			dfs(n);
		}else {
			return;
		}
	}
	/**
	 * 
	 * @param i 给定结点的下标,
	 * @return	返回结点i的第一个且没有被访问过的邻接结点,没有返回-1
	 */
	private int getFirst(int i) {
		for(int j=0;j<vertex.size();j++) {
			if(edges[i][j]>0&&!isVisited[j]) {
				return j;
			}
		}
		return -1;
	}
	
	/*
		一下都是图的基本操作
	*/
	
	//添加结点
	public void add(String str) {
		vertex.add(str);
	}
	//添加边
	public void addEdges(int a,int b,int value) {
		edges[a][b]=value;
		edges[b][a]=value;
		numOfEdge++;
	}
	//返回结点的个数
	public int getNumOfVertex() {
		return vertex.size();
	}
	//根据结点返回权值
	public int getValue(int a,int b) {
		return edges[a][b];
	}
	//显示图对应的矩阵
	public void show() {
		for(int[] arr:edges) {
			System.out.println(Arrays.toString(arr));
		}
	}
	//返回边的数目
	public int getNumEdges() {
		return numOfEdge;
	}
	//返回下标对应的结点
	public String getValueOfVertex(int a) {
		return vertex.get(a);
	}
}

广度优先:

	广度优先也是顾名思义,横向搜索的广度优先的原则,给一个结点i,找到结点i的所有邻接结点。再从找到的结点当中进行广度优先遍历。
	代码实现:
/**
 * 
 * @author 楠
 *
 */
//图
class graph{
	public ArrayList<String> vertex;//存储结点的字符串数组
	public int[][] edges;//邻接矩阵
	public int numOfEdge;//边的个数
	public boolean[] isVisited;//辅助遍历工具,用来判断一个结点是否被访问过
	//构造器
	public graph(int n) {//初始化图
		vertex=new ArrayList<String>(n);
		edges=new int[n][n];
		numOfEdge=0;
	}
	//广度优先遍历图
	public void bfs() {//广度优先遍历只从一个遍历一次就可以了
		isVisited=new boolean[vertex.size()];
		bfs(0);
		System.out.println();
	}
	private void bfs(int i) {
		LinkedList<Integer> queue = new LinkedList<Integer>();//队列存储遍历出来的结点
		System.out.print(getValueOfVertex(i)+"--");
		queue.addLast(i);
		isVisited[i]=true;	
		while (!queue.isEmpty()) {//队列空的时候就遍历完了
			int w=queue.removeFirst();
			int n=getFirst(w);	
			while (n!=-1) {//找到所有的邻接结点
				queue.addLast(n);
				System.out.print(getValueOfVertex(n)+"--");
				isVisited[n]=true;
				n=getFirst(w);
			}
		}
		
	}
	/**
	 * 
	 * @param i 给定结点的下标,
	 * @return	返回结点i的第一个且没有被访问过的邻接结点,没有返回-1
	 */
	private int getFirst(int i) {
		for(int j=0;j<vertex.size();j++) {
			if(edges[i][j]>0&&!isVisited[j]) {
				return j;
			}
		}
		return -1;
	}
	
	/*
		一下都是图的基本操作
	*/
	
	//添加结点
	public void add(String str) {
		vertex.add(str);
	}
	//添加边
	public void addEdges(int a,int b,int value) {
		edges[a][b]=value;
		edges[b][a]=value;
		numOfEdge++;
	}
	//返回结点的个数
	public int getNumOfVertex() {
		return vertex.size();
	}
	//根据结点返回权值
	public int getValue(int a,int b) {
		return edges[a][b];
	}
	//显示图对应的矩阵
	public void show() {
		for(int[] arr:edges) {
			System.out.println(Arrays.toString(arr));
		}
	}
	//返回边的数目
	public int getNumEdges() {
		return numOfEdge;
	}
	//返回下标对应的结点
	public String getValueOfVertex(int a) {
		return vertex.get(a);
	}
}

你可能感兴趣的:(java,算法,数据结构)