用深度优先搜索输出全排列

马上就要蓝桥杯,算法好多都不会,最近在读啊哈磊的《啊哈算法》,这本书挺通俗易懂,尤其对于我这种比较菜的人哈哈。下面就谈一谈用dfs思想解决全排列问题,所谓dfs就是深度优先搜索(Depth First Search)。
下面先给出一个dfs的基本函数模型。

void dfs(int step)
{
	判断边界
	尝试每一种可能 for(i=1;i<=n;i++)
	{
		继续下一步dfs(step+1); //这里也运用了递归思想
	}
	返回 
}

举个例子,假如你手里有三个球分别标记1,2,3号,现在你的面前有三个盒子(同样1,2,3号),你需要将三个球放入三个盒子中,共有几种排列方式,这个当然很容易算,直接枚举就可以了,这是三位的全排列,那如果是位数比较大总不能枚举吧,所以我们需要一个程序解决这个问题,先供上代码

#include<stdio.h>
int a[10],book[10],n;//a这个数组用来当盒子装球,book数组用来标记某号球是否还在手里,n为盒子数
//c语言全局变量在没用赋值以前默认为0 
void dfs(int step)
{
	int i;
	if(step==n+1)//表示现在站在n+1个盒子面前,前面n个盒子已经排好序 
	{
		for(i=1;i<=n;i++)
		{
			printf("%d",a[i]);//输出这种排列 
		}
		printf("\n");
		return;//返回到最近一次调用dfs函数的位置 
	}
	for(i=1;i<=n;i++)
	{
		if(book[i]==0)//book[i]=0表示某号球还没有放入盒子中 
		{
			a[step]=i;//将i号球放入第step个盒子中 
			book[i]=1;//book[i]=1表示i号球已经不在手里 
			dfs(step+1);//递归调用 
			book[i]=0;//将之前放入的球拿出来,才可以进入下一次排列 
		}
	}
	return;
 } 
 int main()
 {
 	scanf("%d",&n);
 	dfs(1);//最先站在1号盒子面前 
 	getchar();
 	getchar();
 	return 0;
 }

看完代码如果还有点迷茫,大家可以在纸上自己模拟一下过程,比如要输出三位的全排列,先输入n=3
进入dfs函数,第一个if语句显然不成立,则马上进入for循环,当i等于1时判断 if 语句,现在1号球在手上(if语句成立),然后将1号球放入1号盒子中,之后进入dfs(2)的for循环,发现i=1时if语句不成立,因为刚才已经把1号球放入了1号盒中,以此类推,当i等于2时成立,将2号球放入2号盒子,进入dfs(3),又将3号球放入3号箱子里,此时进去dfs(4)其实根本没有4号盒子,现在将进入第一个if语句,输出现在这种全排列----->1 2 3,这时候return到dfs(3)函数中将3号球取出,此时dfs(3)中的for循环已经进行到i=3,结束return返回dfs(2)中,再将2号球取出,此时这里的for循环还没有进行到底(此时是i=2),下一步进行i等于3循环,将刚刚取出的3号球放入2号盒子中,再进行dfs(3),把2号球放入3号盒子中,然后程序再次进入到dfs(4)中,第一个if又成立了,输出现在这种全排列----->1 3 2,然后继续return到dfs(3)中…以此类推最后输出3位的所有全排列。
下图是我运行3的全排列的截图
在这里插入图片描述
ps:在这个程序中最多可以输出9位的全排列,如果想输出更大的,只需要更改全局变量即可。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

囿于之间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值