初次走入深搜DFS

本次内容就是我们一直提起的深搜DFS算法,在搜索当中有一句口诀,深搜用递归,广搜用队列,深搜是类似于树的先序遍历,我们这里用一个hdu1016的实例来理解DFS。







深搜的核心思想:


深搜的伪代码如下所示:


下面我们根据如图所示的伪代码来进行代码实现:

1开始我们将除第一列都认为是邻值,进行初始化 。要注意的是我们这里定的默认值不能用0,因为容易与创建数据的默认值弄混。

2在开始dfs开始的时候就要进行count++即伪代码中的time,将此时的startNode即伪代码中的u涂色 将值改为1,以防止它多次被访问。在回退之后要重新洗白,恢复其默认值(-1)。以便于下一次访问遍历。

3我们要注意的是这里的显示print函数即显示路径,因为此时我们只能从子找到父,这里是逆序,我们就要重新new一个数组index来放正序即从父到子。这里我们尤其要注意我们这里用的index[]和parent[]和startNode 放的都是下标,而不是真正的值。最后显示值的时候要用a[index[]]来输出值。

package cn.hncu.serch.dfs;

import java.util.Scanner;

public class SerchMethodDFS {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()){
			int n=sc.nextInt();
			int[] a=new int[n];//存储字节数值
			int[] color=new int[n];//存放搜索标志 -1表示未被搜索
			int[] parent=new int[n];//存放父节点 -1表示null
			//搜索前的初始化
			for (int i = 0; i <n; i++) {
				a[i]=i+1;
				color[i]=-1;
				parent[i]=-1;
			}
			int startNode=0;
			int count=0;
			dfs(a,color,parent,startNode,count);
		}
	}

	private static void dfs(int[] a, int[] color, int[] parent, int startNode,int count) {
		count++;
		color[startNode]=1;
		if (count==a.length && isPrime(a[startNode]+a[0])) {
			parent[0]=startNode;
			print(a,parent);
		}
		for (int v = 1; v < a.length; v++) {
			if (color[v]==-1 && isPrime(a[startNode]+a[v])) {
				parent[v]=startNode;
				dfs(a, color, parent, v, count);
				//回退的话,我们要保留现场,将之前的还原。
				color[v]=-1;
				parent[v]=-1;
			}
		}
	}

	private static void print(int[] a, int[] parent) {
		//index数组当中放的是搜索结果序列每个元素的索引位置 正序(父---子) 而parent数组当中放的是反序(子---父)
		int[] index=new int[parent.length];
		int p=0;
		
		//这里我们所用的parent记录的都是下标而不是a数组指向的值。
		for (int i = 0; i < parent.length; i++) {
			index[parent.length-1-i]=parent[p];
			p=parent[p];
		}
		for (int i = 0; i < index.length; i++) {
			if(i<index.length-1){
				System.out.print(a[index[i]]+"  ");
			}else{
				System.out.println(a[index[i]]);
			}
		}
		
	}

	private static boolean isPrime(int n) {//判断是否为素数代码
		if(n==2){
			return true;
		}
		for(int i=2;i*i<=n;i++){
			if(n%i==0){
				return false;
			}
		}
		
		return true;
	}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值