本次内容就是我们一直提起的深搜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;
}
}