【非递归】全排列

题目

列出所有数字1到数字n的连续自然数的排列,要求所产生的任一数字序列中不允许出现得复数字。
输入
一个数,n
输出
所有的排列,一行一个

思路

生成排列:
① 从后面向前找,直到找到一个顺序(由大到小)为止。
算法为:j=n;

while (a[j]<a[j-1]) j--;

② 然后在a[j],a[j+1],…,a[n]中找出一个比a[j-1]大的最小的数,算法为:

     p=j;
     for(i=j+1;i<=r;i++)
        if (a[i]>a[j-1]&&a[i]<a[p]) p=i;

③ 交换a[p]与a[j-1]
④ 再将a[j],a[j+1],…,a[n]由小到大排序

代码

#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[11],j=1,k,p,l;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	  a[i]=i;    //生成初始序列
	for(int i=2;i<=n;i++) j=j*i; //算出有多少排列
	for(int i=1;i<=j;i++){
		for(k=1;k<=n;k++)
		  printf("%d ",a[k]); //输出第i种排列
		printf("\n");
		if(i==j) break;//后面生成新排列
		for(k=n-1;k>=1;k--)  //刚刚说的
		  if(a[k]<a[k+1]) break;
		p=k+1;
		for(l=k+1;l<=n;l++)  
		  if(a[l]>a[k]&&a[l]<a[p]) p=l;
		l=a[p];a[p]=a[k];a[k]=l;
		sort(a+1+k,a+1+n); 
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值