博客
关于我
深度优先dfs求解两点间所有路径
阅读量:323 次
发布时间:2019-03-04

本文共 4833 字,大约阅读时间需要 16 分钟。

邻接表:
dfs4(a,start,end,visited,stack,-1)//递归
dfs5(a,start,end);//非递归

邻接矩阵:(可以直接用矩阵数据计算路径长度)
dfs6(m,start,end,visited,stack,-1);//递归
dfs7(m,start,end);//非递归

递归的思路来自https://blog.csdn.net/hackersuye/article/details/79044555
非递归是自己做的
大家可以试试。

邻接表和邻接矩阵的写法是来自《天勤高分笔记数据结构》。
邻接表

package dfs;class   AGraph{   	int n;	int e=0;	VNode adjlist[];	public AGraph(int n) {   		super();		this.n = n;		adjlist=new VNode[n];	}			}package dfs;class ArcNode{   	int adjvex;  ArcNode nextarc;	int weight;//weight就是adjlist[i]->adjvex的权重	//对应于邻接矩阵的权重m[i][adjvex]		AGraph a;//记录边数时,需要图a	int edge_type=0;//初始化为回边(P99.8)	public ArcNode(int adjvex, AGraph a) {   		super();		this.adjvex = adjvex;		this.a = a;		a.e+=1;	}					public ArcNode() {   		}	public ArcNode (int adjvex){   		this.adjvex=adjvex;	};		}package dfs;class VNode{   //邻接矩阵的顶点也可以用这个	ArcNode firstarc;	char info;	int level;//对应于99.8,对每个点,都要有层级		public VNode(char info) {   				this.info = info;	}	int ini=1;//用于利用邻接表非递归输出全部路径的DFS	//在该次应该指向链接表的哪一个arc	//初始值为1,即firstarc;若大于1,不停地取nextarc,	//直到找到对应的   第ini边	}

邻接矩阵

package dfs;public class VertexType {   int no;int ini=0;//用于利用邻接矩阵非递归输出全部路径的DFS//这里的ini是指向的顶点数字(因为用邻接矩阵总要从后向前遍历)//不是VNode里面的第几个}package dfs;public class MGraph {   int n;int e=0;//n为顶点数,e为边数//int edges[][];VertexType  vex[];int edges[][];			public MGraph(int n) {   				this.n = n;		edges=new int[n][n];		vex=new VertexType[n];		for(int i=0;i<vex.length;i++)			vex[i]=new VertexType();	}public void set(int i,int j){     edges[i][j]=1;  //如果是无向图的话  edges[j][i]=1;  e+=2;}	}

4个方法

public static void dfs4(AGraph a,int start,int end,			int visited[],int stack[],int top)		{   	visited[start]=1;		stack[++top]=start;		if(start==end) {   			System.out.println("成功");			for(int i=0;i<=top;i++)			System.out.print(stack[i]+" ");			System.out.println("");//出栈			top--;			visited[end]=0;			//visited[stack[top]]=0;top--;			return;		}		ArcNode arc=a.adjlist[start].firstarc;		while(arc!=null)		{   if(visited[arc.adjvex]==0)			dfs4(a,arc.adjvex,end,visited,stack,top);		arc=arc.nextarc;		}		if(arc==null)  {   			top--;visited[start]=0;			//visited[stack[top]]=0;top--;		}	}				public static void dfs5(AGraph a,int start,int end)	{   //每次进栈一个元素或出栈一个元素	int visited[]=new int[a.n];//初始化为0	int stack[]=new int[a.n];	int top=-1;	stack[++top]=start;//stack存放的是adjlist中某一个的位置	visited[start]=1;	while(top!=-1)	{   	ArcNode arc=null;	int x=stack[top];	//在if else下面统一出栈,设定为未访问	if(x==end)  //栈输出    //9在这里是终点	{   	System.out.println("成功");		for(int i=0;i<=top;i++)		System.out.print(stack[i]+" ");		System.out.println("");			}	else//m是指明arc是x指向的第几个顶点//这个顶点必须满足://①未被访问//②m必须大于等于ini(小于ini的都已经出栈或不行了,不用考虑)		{   arc=a.adjlist[x].firstarc;		int m=1;		while(arc!=null)		{   if(visited[arc.adjvex]==0&&m>=a.adjlist[x].ini)			{   stack[++top]=arc.adjvex;			visited[arc.adjvex]=1;break;}			else {   				arc=arc.nextarc;m++;}}		}	if(arc==null)//此处逻辑为先出栈,出栈的元素指向的边还原为firstarc//出栈的元素b一定是出栈后栈顶元素a指向的某一个顶点//我们找到b是a的第m个顶点,把a的ini设置为m+1//使其不要重复搜索前m个//(前面的做法一定是按顺序的,说明前m个已经搜过)	{   	int y=stack[top--];//出栈			visited[y]=0;			a.adjlist[y].ini=1;					if(top>=0)			 {     ArcNode ar=a.adjlist[stack[top]].firstarc;		 	int count=1;			//由上面,我们知道进栈的一定>=ini		 	//所以首先ar要变成ini			while(count<a.adjlist[stack[top]].ini)			{   ar=ar.nextarc;			count++;}			//再往下找			int number=ar.adjvex;			while(number!=y)			{   a.adjlist[stack[top]].ini++;			ar=ar.nextarc;			number=ar.adjvex;			}			a.adjlist[stack[top]].ini++;		 }	}      }	}									public static void dfs6(MGraph m,int start,int end,			int visited[],int stack[],int top)		{   	visited[start]=1;		stack[++top]=start;		if(start==end) {   			System.out.println("成功");			for(int i=0;i<=top;i++)			System.out.print(stack[i]+" ");			System.out.println("");//出栈			top--;			visited[end]=0;			//visited[stack[top]]=0;top--;			return;		}						for(int i=0;i<m.n;i++)		if(m.edges[start][i]==1&&visited[i]==0)		{   			dfs6(m,i,end,visited,stack,top);		}		top--;		visited[start]=0;			}								public static void dfs7(MGraph m,int start,int end)	{   //每次进栈一个元素或出栈一个元素	int visited[]=new int[m.n];//初始化为0	int stack[]=new int[m.n];	int top=-1;	stack[++top]=start;//stack存放的是vex中某一个的位置	visited[start]=1;	while(top!=-1)	{   	int x=stack[top];	int ii=m.n;//ii为条件	//在if以及else下面统一出栈	if(x==end)  //栈输出    	{   	System.out.println("成功");		for(int i=0;i<=top;i++)		System.out.print(stack[i]+" ");		System.out.println("");			}	else//m是指明arc是x指向的第几个顶点//这个顶点必须满足://①未被访问//②ii必须大于等于x的ini(小于ini的都已经出栈或不行了,不用考虑)//③ii必须与x有边	{   		for(ii=m.vex[x].ini;ii<m.n;ii++)		if(visited[ii]==0&&m.edges[x][ii]!=0)		{   stack[++top]=ii;		visited[ii]=1;break;}				}								if(ii==m.n)//此处逻辑为先出栈,出栈的元素指向的边还原为0//出栈的元素y一定是出栈后栈顶元素a指向的某一个顶点//把a的ini设置为y+1//使其不要重复搜索前y个顶点//(前面的做法一定是按顺序的,说明前y个已经搜过或者根本不满足条件)		{   	int y=stack[top--];//出栈			visited[y]=0;			m.vex[y].ini=0;					if(top>=0)				m.vex[stack[top]].ini=y+1;		   		}      }	}
你可能感兴趣的文章
无锁并发框架-Disruptor的使用(二)
查看>>
Android wm命令
查看>>
Android4.4 平板背光设置
查看>>
spring boot@Value和bean执行顺序问题
查看>>
codeforces The Eternal Immortality 题解
查看>>
蓝桥杯 历届试题 幸运数 (堆+DFS)
查看>>
微信js-sdk使用简述(分享,扫码功能等)
查看>>
selenium 的介绍和爬取 jd数据
查看>>
mxsrvs支持thinkphp3.2伪静态
查看>>
mui HTML5 plus 下载文件
查看>>
DSP开发板准备
查看>>
c++中ifstream及ofstream超详细说明
查看>>
c++中explicit和mutable关键字探究
查看>>
c语言结构体字节对齐详解
查看>>
linux c/c++面试知识点整理(八)
查看>>
Deep residual learning for image recognition
查看>>
IO控制器
查看>>
Python 知识点总结篇(3)
查看>>
爬取网易科技滚动新闻
查看>>
vuex modules
查看>>