深度优先搜索DFS-全排列

深度搜索-全排列

刚学完深度优先算法的初级使用,对深度优先算法有了一点自己的理解,做一点简单的分享。

算法名称

为什么叫深度优先,比如做全排列,我每都把所有数排一遍,作为一次尝试,将全排列比作给箱子中放卡片,每个卡片只能放进一个箱子,放完所有卡片,视为一种排列方式,对于深度优先来说,每次放置卡片进入一个箱子后,不再考虑当前箱子还能放什么卡片,而是去下一个箱子,继续放还在手上的卡片,就是说,放好一个卡片后,之研究下一个箱子放什么卡片,一直到放置完所有的卡片。每次都是深入的研究当前的顺序,直到结束(可以说是一条道走到黑)。

算法思路

上面说了,每次放好,就去下一个,直到结束,这只是其中的一种顺序,并不是全部,所以,要将全部的顺序都列举出来,那就要在结束后,在将放好的卡片取出,再看能放其他什么卡片,放完后,再回上一步,直到回到第一步,并将第一步的所有放法都尝试一遍,然后结束。

每次全部放完后,取出最后一个盒子中的卡片,尝试放置其他卡片,发现最后一个盒子没有其他卡片可以选择,然后,回到倒数第二个盒子,取出卡片,现在,手中有两张卡片,将没有在倒数第二个盒子中放过的卡片,放入该盒子,在去下一个盒子放剩下的一张,完成后,再取出,退到倒数第二个盒子,此时,两张都已放过,在退到倒数第三个盒子,取出卡片,此时有三张卡片,先放一张没放过的卡片进去,在去下一个盒子,放完后,会再回到第三个盒子,在尝试其他卡片,一次类推,直到结束。

代码实现

#include<stdio.h>
//*四个参数 第一个表示在第几个盒子面前 第二个盒子数组 第三个标记数组 第四个全排列的数字*
void dfs(int tmp,int a[],int book[],int n);

int main()
{
	int b,c;
	int a[100],n,book[100]={}; //*a数组相当于盒子,book数组是标记,如果卡片在手里,对应i就为0,在盒子里就为1*
	scanf("%d",&n);
	dfs(1,a,book,n);调用函数
	return 0;
}

void dfs(int tmp,int a[],int book[],int n)
{
	int i;
	if(tmp==n+1)//*递归函数出口,站到不存在的盒子面前,表示排列结束,输出结果*
	{
		for(i=1;i<=n;i++)
		{
			printf("%d",a[i]);
		}
		printf("\n");
		return;//*回到倒数第一个盒子*
	}
	for(i=1;i<=n;i++)
	{
		if(book[i]==0) //*book[i]=0表示该卡片没有放进箱子里,可以放进盒子里*
		{
			a[tmp]=i;//*将卡片放进盒子里*
			book[i]=1;//修改标记,卡片不在手中了
			dfs(tmp+1,a,book,n);//*去下一个盒子*
			book[i]=0;//*取出放入的卡片,准备给tmp 盒子中放入其他卡片***最关键的一步*
		}
	}
	return;//*回到上一次调用的地方*
}

总结

其实算法思路和代码的实现不是很难,关键是代码中递归调用的过程不好理解,对于递归的过程,最好在纸上自己实现以下,加深印象。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值