数据结构之深度优先遍历

深度优先遍历(DSF):

思想:可以使用递归和非递归来完成dsf

简述一下非递归方法的思想:是使用队列还是栈呢?首先要明确队列和栈各自的特点,队列是先进先出,
栈是后进先出出,想一想深度优先检索,重点是在深度,要想深度向下,就需要沿着一条线从一个节点一直向下
遍历直到没有节点可遍历位置。那么问题来了,要想沿着一条线不断向下,就需要不断的找起始节点的下一个节点
再下一个节点,再再下一个节点......直到最后,可以通过一个节点的邻接节点来找到其“下一个节点”,
所以使用栈,从第一个节点开始,不断的入栈弹栈,利用栈的后进先出的特点来找出节点的某一邻接节点作为
遍历路径上的下一个节点

接下来上张图来说明深度遍历


比如从A开始,找A的邻接节点有:B,F比如选中B作为A的下一个节点,此时A已经遍历过,遍历过的节点以后便不用再遍历
再看B的邻接节点有C,I,G选择C作为B的下一个节点,此时B也已经遍历过了,一次类推比如遍历的顺序为A,B,C,D,E,F,G,H,
没有能往下继续遍历的节点,所以开始回溯,看是否还有节点没有遍历完,首先回溯到节点G,发现G的邻接节点已经
完全遍历完了,在回溯到F,同样如此,然后F,E,D,C依次回溯,到C发现C的邻接节点I没有遍历,所以把I作为下一个节点开始遍历
,遍历完再回溯,直达回溯到A节点为止。所以应为再回溯的过程中要找上一个节点,所以用栈非常适合深度优先遍历

深度优先遍历既可以使用递归方法又可以使用非递归方法

下面呈上一段详细代码

package SevenProvience.tital2;

import java.util.Stack;

public class DFS {
	//存储节点信息
	private char[] vertices;
	//存储边信息(邻接矩阵)
	private int[][] arcs;
	//图的节点数
	private int vexnum;
	//记录节点是否已被遍历
	private boolean[] visited;
	//初始化
	public DFS(int n){
		vexnum=n;
		vertices=new char[n];
		arcs=new int[n][n];
		visited=new boolean[n];
		//将矩阵所有的边都初始化为0
		for(int i=0;i<vexnum;i++){
			for(int j=0;j<vexnum;j++){
				arcs[i][j]=0;
			}
		}
	}
	//添加边(无向图)
	public void addEdge(int i,int j){
		//边的头尾不能为同一个节点 
		if(i==j)return;
		arcs[i][j]=1;
		arcs[j][i]=1;
	}
	//设置节点集
	public void setVertices(char[] vertices){
		this.vertices=vertices;
	}
	//设置节点访问标记
	public void setVisited(boolean[] visited){
		this.visited=visited;
	}
	//打印遍历节点
	public void visit(int i){
		System.out.print(vertices[i]+" ");
	}
	//非递归方法是实现深度优先遍历
	public void DFSTraverse(){
		//初始化节点遍历标记
		for(int i=0;i<vexnum;i++){
			visited[i]=false;
		}
		//创建一个栈
		Stack<Integer> s=new Stack<Integer>();
		//对非联通图执行循环进行遍历以至于所有节点都遍历到
		//若是连通图该for循环只执行一次
		for(int i=0;i<vexnum;i++){
			if(!visited[i]){
				//连通子图起始节点
				s.add(i);
				do{
					//出栈
					int curr=s.pop();
					//如果节点还没有被遍历到,则遍历该节点并将该节点入栈用来遍历其子节点
					if(visited[curr]==false){
						//遍历并打印
						visit(curr);
						visited[curr]=true;
						//没遍历的子节点入栈
						for(int j=vexnum-1;j>=0;j--){
							if(arcs[curr][j]==1&&visited[j]==false){
								s.add(j);
							}
						}
					}
				}while(!s.isEmpty());
			}	
		}
	}
	//从第i个节点开始深度优先遍历
	private void traverse(int i){
		//标记第i个节点已被遍历
		visited[i]=true;
		//打印当前遍历的节点
		visit(i);
		//遍历邻接矩阵中第i个节点的直接连通关系
		for(int j=0;j<vexnum;j++){
			//目标节点与当前节点直接连通并没有被访问,递归遍历
			if(arcs[i][j]==1&&visited[j]==false){
				traverse(j);
			}
		}
	}
	//图的深度优先遍历(递归法)
	public void DFSTraverse1(){
		//初始化节点遍历标记
		for(int i=0;i<vexnum;i++){
			visited[i]=false;
		}
		//从没有被遍历的节点开始深度遍历
		//连通图的话这个循环只会执行一次
		for(int i=0;i<vexnum;i++){
			if(visited[i]==false)
			traverse(i);
		}
	}
	
}
package SevenProvience.tital2;

public class test {

	public static void main(String[] args) {
		DFS g = new DFS(9);
        char[] vertices = {'A','B','C','D','E','F','G','H','I'};
        g.setVertices(vertices);

        g.addEdge(0, 1);
        g.addEdge(0, 5);
        g.addEdge(1, 0);
        g.addEdge(1, 2);
        g.addEdge(1, 6);
        g.addEdge(1, 8);
        g.addEdge(2, 1);
        g.addEdge(2, 3);
        g.addEdge(2, 8);
        g.addEdge(3, 2);
        g.addEdge(3, 4);
        g.addEdge(3, 6);
        g.addEdge(3, 7);
        g.addEdge(3, 8);
        g.addEdge(4, 3);
        g.addEdge(4, 5);
        g.addEdge(4, 7);
        g.addEdge(5, 0);
        g.addEdge(5, 4);
        g.addEdge(5, 6);
        g.addEdge(6, 1);
        g.addEdge(6, 3);
        g.addEdge(6, 5);
        g.addEdge(6, 7);
        g.addEdge(7, 3);
        g.addEdge(7, 4);
        g.addEdge(7, 6);
        g.addEdge(8, 1);
        g.addEdge(8, 2);
        g.addEdge(8, 3);
        
        System.out.println("深度优先遍历(非递归):");
        g.DFSTraverse();
        System.out.println();
        System.out.println("深度优先遍历(递归):");
        g.DFSTraverse1();
	}

}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值