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; }