算法竞赛入门经典:第七章 暴力求解法 7.5枚举排列

/*
枚举排列:
输入整数n,按字典顺序从小到大的顺序输出前n个数的所有排列。两个序列的字典序大小关系等价于从头开始第一个不相同位置处的大小关系。例如,(1,3,2) <(2,1,3)
,字典序最小的排列是(1,2,3,...,n),最大的排列是(n,n-1,n-2,...,1)。n=3时,所有排列的排序结果是:(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)、(3,1,2),
(3,2,1)。

思路:
先打印1,2,3,..n
*/

/*
关键:
1 这里打印的元素可以存放在数组中,可以用递归来实现 void printPermutation(int* iArr,int n,int pos)
2 递归的条件为:数组,下一个元素的下标,数组本身的大小。我们确定第一个元素为1之后,后面需要打印所有的排列,并在排列之前加上之前的元素1
3 if(pos == n)//递归出口,如果下标已经到达数组的个数时,退出
  		for(int k = 0;k < n; k++)//要打印所有元素,否则没有输出
		{
			printf("%d ",iArr[k]);
		}
4 for(int i = 1; i <= n;i++)//确定大排序序列中的第一个元素
5 		for(int j = 0; j < pos; j++)
		{
			if(iArr[j] == i)//剪枝标记,如果该数已经出现过,就不打印
6 		if(!isAppear)//如果元素没有出现,就令当前的i为当前元素
		{
			iArr[pos] = i;
			printPermutation(iArr,n,pos+1);//接下来把第pos个元素确定之后,后面需要进行下一步递归
		}
*/
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1024

void printPermutation(int* iArr,int n,int pos)
{
	if(pos == n)//递归出口,如果下标已经到达数组的个数时,退出
	{
		for(int k = 0;k < n; k++)//要打印所有元素,否则没有输出
		{
			printf("%d ",iArr[k]);
		}
		printf("\n");
		return;
	}
	for(int i = 1; i <= n;i++)//确定大排序序列中的第一个元素
	{
		//确定每个元素
		bool isAppear = false;
		for(int j = 0; j < pos; j++)
		{
			if(iArr[j] == i)//剪枝标记,如果该数已经出现过,就不打印
			{
				isAppear = true;
				break;
			}
		}
		if(!isAppear)//如果元素没有出现,就令当前的i为当前元素
		{
			iArr[pos] = i;
			printPermutation(iArr,n,pos+1);//接下来把第pos个元素确定之后,后面需要进行下一步递归
		}
	}
}

int main(int argc,char* argv[])
{
	int n;
	int iArr[MAXSIZE];
	while(EOF != scanf("%d",&n))
	{
		int pos = 0;
		printPermutation(iArr,n,pos);
	}
	system("pause");
	return 0;
}

你可能感兴趣的:(排列)