图的深度优先搜索(DFS)和广度优先搜索(BFS)

1.遍历

图的遍历,所谓遍历,就是对结点的访问,一个图有那么多的结点,如何遍历这些结点,需要特定的策略,一般有两种访问策略:

深度优先搜索和广度优先搜索


2.深度优先搜索DFS

深度优先搜索,从图的任一顶点V1开始,输出顶点V1,将V1作为当前顶点,寻找当前顶点的邻接点V2,并进行如下判断:如果目前尚未输出顶点V2,则输出V2,V2成为新的当前顶点,继续这个过程;如果V2已经输出,则检查V1的另一个邻接点;如果V1的所有邻接点均已输出,则退回到V1之前的顶点深度优先搜索过程是一个递归过程,程序实现时使用栈记录遍历路径,当遍历一个顶点时,顶点入栈;当某个顶点的所有邻接点均已访问过,则退栈,栈顶顶点又作为当前顶点,继续遍历过程。当栈空时,检查是否已遍历图中所有顶点,若是,说明图为连通图,否则,图是不连通的

具体算法表述如下:

  1. 访问初始结点v,并标记结点v为已访问。

  2. 查找结点v的第一个邻接结点w。

  3. 若w存在,则继续执行4,否则算法结束。

  4. 若w未被访问,对w进行深度优先遍历递归(即把w当做另一个v,然后进行步骤123)。

  5. 查找结点v的w邻接结点的下一个邻接结点,转到步骤3。

例如下图,其深度优先遍历顺序为 1->2->4->8->5->3->6->7


3.广度优先搜索BFS

广度优先搜索是一个迭代的过程,类似于二叉树层序遍历过程,从图中的任一顶点V1开始,将顶点V1入队列,当队列不空时,循环执行:出队列,并输出该顶点,标记该顶点为已输出,将该顶点所有尚未输出的邻接点入队列

具体算法表述如下:

  1. 访问初始结点v并标记结点v为已访问。

  2. 结点v入队列

  3. 当队列非空时,继续执行,否则算法结束。

  4. 出队列,取得队头结点u。

  5. 查找结点u的第一个邻接结点w。

  6. 若结点u的邻接结点w不存在,则转到步骤3;否则循环执行以下三个步骤:

    1). 若结点w尚未被访问,则访问结点w并标记为已访问。
    2). 结点w入队列
    3). 查找结点u的继w邻接结点后的下一个邻接结点w,转到步骤6

如上图,其广度优先算法的遍历顺序为:1->2->3->4->5->6->7->8

4.程序

package graph;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class Graph {
	private ArrayList vertexList; //存储点的链表
	private int[][] edges;  //邻接矩阵,用来存储边
	private Stack<Integer> stack;
	private Queue<Integer> queue;
	
	public Graph(int n){
		this.vertexList=new ArrayList(n);
		this.edges=new int[n][n];
		this.stack=new Stack<Integer>();
		this.queue=new LinkedList<Integer>();
	}
	
	//插入结点
	public void insertVertex(Object vertex){
		vertexList.add(vertexList.size(), vertex);
	}
	
	//插入边
	public void insertEdge(int v1,int v2,int weight){
		edges[v1][v2]=weight;
	}
	
	//深度优先搜索
	public void DFS(boolean[] isVisited){
		int i=this.stack.peek();
		boolean mark=false;
		for(int j=0;j<vertexList.size();j++){
			if(edges[i][j]>0&&!isVisited[j]){
				System.out.print(vertexList.get(j)+"-");
				isVisited[j]=true;				
				this.stack.push(j);
				mark=true;
				DFS(isVisited);
				}
			}
		if(!mark)
			this.stack.pop();
		if(this.stack.isEmpty())
			return;				
	}
	
	public  void initDFS(boolean[] isVisited){
		System.out.print(vertexList.get(0)+"-");
		isVisited[0]=true;
		this.stack.push(0);
		DFS(isVisited);
	}
	
	//广度优先搜索
	public void BFS(boolean[] isVisited){
		if(this.queue.isEmpty())
			return;
		int i=this.queue.poll();
		System.out.print(vertexList.get(i)+"-");
		for(int j=0;j<this.vertexList.size();j++){	
			if(this.edges[i][j]>0&&!isVisited[j]){
				isVisited[j]=true;
				this.queue.add(j);
				}
		}
		BFS(isVisited);
	}
	
	public void initBFS(boolean[] isVisited){
		this.queue.add(0);
		isVisited[0]=true;
	}
	
	public static void main(String[] args){
		int n=8;
		String labels[]={"1A","2B","3C","4D","5E","6F","7G","8H"};
		Graph graph=new Graph(n);
		for(String label:labels)
			graph.insertVertex(label);
        //插入九条边
        graph.insertEdge(0, 1, 1);
        graph.insertEdge(0, 2, 1);
        graph.insertEdge(1, 3, 1);
        graph.insertEdge(1, 4, 1);
        graph.insertEdge(3, 7, 1);
        graph.insertEdge(4, 7, 1);
        graph.insertEdge(2, 5, 1);
        graph.insertEdge(2, 6, 1);
        graph.insertEdge(5, 6, 1);
        graph.insertEdge(1, 0, 1);
        graph.insertEdge(2, 0, 1);
        graph.insertEdge(3, 1, 1);
        graph.insertEdge(4, 1, 1);
        graph.insertEdge(7, 3, 1);
        graph.insertEdge(7, 4, 1);
        graph.insertEdge(6, 2, 1);
        graph.insertEdge(5, 2, 1);
        graph.insertEdge(6, 5, 1);
        
        System.out.println("深度优先搜索序列为:");
        boolean[] isVisited=new boolean[8];   
        graph.initDFS(isVisited);
        graph.DFS(isVisited);
        System.out.println();	
        System.out.println("广度优先搜索序列为:");
        isVisited=new boolean[8];   
        graph.initBFS(isVisited);
        graph.BFS(isVisited);       
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值