顶点

class Vertex
	{
		public char label;
		public boolean wasVisited;
		public Vertex(char lab)
		{
			label=lab;
			wasVisited=false;
			
		}
	} 

顶点对象放在数组中然后用下标指示用数组vertexList存储顶点对象。顶点也可以放在链表或其他数据结构中。

图搜索

    1深度优先搜索

            *规则1 如果可能,访问一个 邻接的未访问顶点标记他并把它放入栈中

            *规则2 当不能执行规则1时,如果栈不为空,就从栈中弹出一个节点

            *规则3 如果不能执行1,2则完成了整个搜索过程

 

public void dfs()
	{
		vertexList[0].wasVisited=true;//将vertexList中的第一个节点标记已访问
		visited(vertexList[0]);//访问节点
		Stack<Integer> stack=new Stack<>();
		while(!stack.isEmpty())//     *规则3 如果不能执行1,2则完成了整个搜索过程
		{
			int v = getUnvisitedVertex(stack.peek());
			if(v==-1)
			{
				stack.pop();//  *规则2 当不能执行规则1时,如果栈不为空,就从栈中弹出一个节点
			}
			else// *规则1 如果可能,访问一个 邻接的未访问顶点标记他并把它放入栈中
			{
				vertexList[v].wasVisited=true;//将vertexList中的第v个节点标记已访问
				visited(vertexList[v]);
				stack.push(v);
			}
		}
		for(int j=0;j<vertexList.length;j++)//结束遍历后对还原节点访问标志
		{
			vertexList[j].wasVisited=false;
		}
	}

   2 广度优先搜索

            *规则1 访问下一个未访问的邻接点(如果存在),这个顶点必须是当前顶点的邻接点,并标记他,并把它插入到队列中

            *规则2  如果因为未访问顶点而不能执行规则1.那么从队头取一个顶点?(如果存在),并使其成为当前顶点。

            *规则3 如果因为队列为空而不能执行规则2,则搜索结束

public void bfs()
	{
		vertexList[0].wasVisited=true;
		visited(vertexList[0]);
		int v2;
		LinkedList<Integer> queue=new LinkedList<>();
		queue.offer(0);
		while(!queue.isEmpty())// *规则3 如果因为队列为空而不能执行规则2,则搜索结束
		{
			int v = queue.poll();//规则2  如果因为未访问顶点而不能执行规则1.那么从队头取一个顶点?(如果存在),并使其成为当前顶点。
			while((v2=getUnvisited)!=-1)//    *规则1 访问下一个未访问的邻接点(如果存在),这个顶点必须是当前顶点的邻接点,并标记他,并把它插入到队列中
			{
				vertexList[v2].wasVisited=true;
				visit(vertexList[v2]);
				queue.offer(v2);
			}
		}
		for(int j=0;j<vertexList.length;j++)//结束遍历后对还原节点访问标志
		{
			vertexList[j].wasVisited=false;
		}
	}

(以上是数据结构与算法Java版中的部分代码)

通过一道递归题帮助理解图搜索

leetcode 78

Note: 
Elements in a subset must be in non-descending order. 
The solution set must not contain duplicate subsets. 
For example, 
If nums = [1,2,3], a solution is:


[3], 
[1], 
[2], 
[1,2,3], 
[1,3], 
[2,3], 
[1,2], 
[] 
]

思路分析:题意就是求一个数组集合的所有子集

public static boolean[] v=new boolean[100];//记录该位置的元素是否被选取
	public static List<List<Integer>> res=new ArrayList<>();//存储结果
	
	public List<List<Integer>> subsets(int[] nums)
	{
		robot(0,nums);
		return res;
	}


	private void robot(int idx, int[] nums) {
		if(idx>=nums.length)
		{
			List<Integer> r= new ArrayList<Integer>();
			for(int i=0;i<nums.length;i++)
			{
				if(v[i])
				{
					r.add(nums[i]);
				}
			}
		}
		//有两种决策选取idx元素则v[idx]为true否则为false
		v[idx]=true;
		robot(idx+1,nums);//选取  
		v[idx]=false;
		robot(idx+1,nums);//不选
				
		
	}

深度优先应用(栈 递归)

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

nxn国际象棋上摆摆n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

 思路:从0-n列依次摆 在第0列摆皇后可以有0-n行的位置可以选择摆一个皇后后问题就变成从(1-n)列摆皇后用path记录皇后摆的位置

假如皇后摆在第i行位置则path[0]=i,zheng记录有左下到右上可以找出规律 此时 不可用摆的位置为0+i zheng[0+i]=false  即如果列记为idx则 

zheng[idx+i]=false 即如果以后皇后的位置如果满足index+i就不能摆同理fan记录有左上到右下规律 idx-i相等就不能摆 因为数组索引不能为负i所以用x-i+n作为索引记录

public static List<List<String>> ress=new ArrayList<>();//记录结果
	public static boolean[] hang = new boolean[100];//记录行是否可以摆皇后

	public static int[] path = new int[100];//记录皇后摆放的列
	public static boolean zheng[] = new boolean[100];//记录左下到右上方向上是否可以摆皇后
	public static boolean fan[] = new boolean[100];//记录左上到右下方向是否可以摆皇后
	public void dfs(int idx,int n)
	{
		if(idx>=n)//如果搜索到头就按题目要求输出结果
		{
			List<String> chess = new ArrayList<String>();
			for(int i=0;i<n;i++)
			{
				String temp="";
				for(int j=0;j<n;j++)
				{
					if(j==path[i])
					{
						temp+="q";
					}
					else
					{
						temp+=".";
					}
					
				}
			}
			ress.add(chess);
		}
		
		
		for(int i=0;i<n;i++)//该皇后初始摆放行位置可以从0到n-1;
		{
			if(!hang[i]&&!zheng[idx+i]&&!fan[idx-i+n-1]&&!fan[idx-i+n-1])//判断该位置能否摆皇后
			{
				//能摆
				path[idx]=i;//记录对应列皇后摆放的行
				hang[i]=true;//之后该行不能摆皇后
				zheng[idx+i]=true;//对应斜线不能摆皇后
				fan[idx-i+n-1]=true;//对应斜线不能摆皇后
				dfs(idx+1,n);//深度搜索
				hang[i]=false;//这个位置摆完后还原现场
				zheng[idx+i]=false;
				fan[idx-i+n-1]=false;
			}
		} 

参考资料:https://www.bilibili.com/video/av19345520/ 

             数据结构与算法(Java版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值