深度优先dfs求解两点间所有路径

18 篇文章 0 订阅

邻接表:
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;
		   
		}
      }
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值