10个重复?草狼兄弟,我有点生气了。
请仔细看一下代码,我是故意多输出10次,以验证当达到排列的最大值后可以返回到第一组排列重新开始。
请仔细看一下代码,我是故意多输出10次,以验证当达到排列的最大值后可以返回到第一组排列重新开始。

重剑无锋,大巧不工
程序代码:#include<stdio.h>
#include<stdlib.h>
void fun(int n,int k,int *p);
int main()
{ int m,a,b;
struct x{
int n;
int k;
int *p;
}*ptr;
printf("输入:\n");
scanf("%d",&m);
ptr=(struct x*)malloc(m*sizeof(struct x));
for(a=0;a<m;a++)
{
scanf("%d %d",&ptr[a].n,&ptr[a].k);
ptr[a].p=(int *)malloc(sizeof(int)*ptr[a].n+1);
for(b=0;b<ptr[a].n;b++)
scanf("%d",&ptr[a].p[b]);
printf("--------------------------------------------\n");
}
for(a=0;a<m;a++)
fun(ptr[a].n,ptr[a].k,ptr[a].p);
for(a=0;a<m;a++)
free(ptr[a].p);
free(ptr);
return 0;
}
int m(int *pti,int n,int a);/*这个函数的功能有两个,当a=0时找出的事最小的一个没有被使用的数,当a!=0时找出的是a之后的最小的那个数(此数大于a小于n),没有找到返回0*/
void fun(int n,int k,int *p)
{ struct date{
char a;
int flag,j;
struct date *front;
struct date *next;
}*head,*q,*t;/*这是节点的结构,a用来存放该节点的数据,flag用来标识该节点还有多少个兄弟节点没有遍历,j只与节点所在的深度有关,记录有多少个子节点*/
int s,*pti,sum,tempt;int *ptc=p;
pti=(int*)malloc(sizeof(int)*n+1);/*pti指向的是一个数组,记录一个数有没有被使用,该数就是数组的下标,0表示没有被使用,1表示已经被使用*/
for(s=1;s<=n;s++)
pti[s]=0;/*报所有的元素的置为0*/
q=head=(struct date*)malloc(sizeof(struct date));/*头结点*/
head->a=0;
head->front=NULL;
head->next=NULL;
head->flag=head->j=n;
for(s=n;s>0;s--)/*初始化开始树(更像是双向链表),就是把给出的排列放入树中*/
{
t=(struct date*)malloc(sizeof(struct date));
t->flag=t->j=s-1;
t->front=q;
t->next=NULL;
t->a=*(ptc);
pti[*(ptc++)]=1;/*记录下已经使用过的元素*/
q->next=t;
q=t;
}
for(sum=0;sum!=k;)
{ t=q;
while(t->flag==0)/*往回找到应该改变的那一个节点*/
{
pti[t->a]=0;
t=t->front;
}
do{
pti[t->a]=0;
tempt=t->a=m(pti,n,t->a);
t=t->front;
}while(tempt==0&&t!=head);/*m函数返回为0的时候,表示没有大于t->a且小于n的没有使用的数,此时为保证从大到小的顺序,要改变上一个节点的数*/
if(t==head&&tempt==0)/*当找到最后的时候,要返回从最小的开始找*/
{
t=t->next;
t->a=m(pti,n,0);
}
else
{t=t->next;}
pti[t->a]=1;
t->flag--;/*一个兄弟没了*/
t=t->next;
while(t!=NULL)/*为t节点后面的节点选择该使用的数*/
{
t->flag=t->j;
t->a=m(pti,n,0);
pti[t->a]=1;
t=t->next;
}
sum++;
}
t=head->next;
printf("输出:\n");
while(t!=NULL)
{
printf("%d ",t->a);
t=t->next;
}
printf("\n");
t=q=head;
while(q!=NULL)
{
t=q;
q=q->next;
free(t);
}
free(pti);
}
int m(int *pti,int n,int a)/*这个函数的功能有两个,当a=0时找出的事最小的一个没有被使用的数,当a!=0时找出的是a之后的最小的那个数(此数大于a小于n),没有找到返回0*/
{
int s;
for(s=1;s<=n&&!a;s++)
if(pti[s]==0)
return s;
for(s=a+1;a&&s<=n;s++)
if(pti[s]==0)
return s;
return 0;
}