全排列的递归解法

本以为学会了递归,没想到用起来还是比较困难。遇到了一个全排列的题目,来再学习体验一下递归思想。

题目大意为输出数列1,2,…n的全排列。

如:1,2,3,的全排列为:

      1,2,3

      1,3,2

      2,1,3

      2,3,1

      3,1,2

      3,2,1

结题思路:

利用递归的思想,把问题的规模不断缩小,分成若干个子问题,那么这题就可以分为:

输出以1开头的全排列

扫描二维码关注公众号,回复: 4955309 查看本文章

输出以2开头的全排列

……

输出以n开头的全排列

这里设定一个储存当前排列的数组AeList,一个散列数组StatusTable,当数字X已经在数组AeList中时,StatusTable[X]为true.

然后,按顺序往数组AeList的第1~n位填数字。现在假设AeList[1]~AeList[index-1]位已经填好,正准备填第index位,则枚举

1~n,如果某个数X还没在AeList[1]~AeList[index-1]位中(即StatusTable[X]==false),则将X填入AeList[X]里,同时StatusTable[X] 

设为false。这时开始处理下一位index+1位,即进入递归.递归结束后在将StatusTable[X]还原为false,这样每次递归结束后都让

StatusTable[X]还原为false,以便下让数组AeList去存储下一个以某个数开头的全排列。

#include<cstdio>

int n;//1~n个整数全排列 
int AeList[10];//存储每次排列的序列 
bool StatusTable[10]={0};//记录某个数是否已经在之前参与排列 

void Arrange(int index)
{
	if(index==n+1)//递归边界,如果已经处理了前n个数,前n个数的某次全排列已经完成 
	{
	   {
		int i;
		printf("[ ");
		for(i=1;i<=n;i++)
		   printf("%d  ",AeList[i]);
		printf("]\n"); 
	   }
	return;
    }
    int x;
    for(x=1;x<=n;x++)//枚举1~n试图将x填入AeList[index](从全局来看是  以1开头的排列,以2开头的排列,……以n开头的排列 ) 
    {
    	if(StatusTable[x]==0)//如果这个数没有参与过排列 
    	{
    		AeList[index]=x;//另AeList的第index位为x,即把x加入当前排列 
    		StatusTable[x]=1;//记录x的状态,表明其已经在排列中 
    		Arrange(index+1);//处理下一位 
    		StatusTable[x]=0;//处理完后还原状态,这样才能在返回上一次层时保证正确 
		}
	}
} 

int main()
{
	n=3; //1~3的全排列 
	Arrange(1);//从 AeList[1]开始填 
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41706331/article/details/86521823