对于1到n的全排列问题,常见的是用递归的方法输出所有的排列,本文是一种非递归的实现方法。具体原理如下:
已知共有n!个排列方式,可以对这些排列方式编号:0到(n!-1),每个编号唯一地对应一个排列方式。循环地根据每个编号来还原出它所对应的排列方式即可。
如何编号呢?以n=4为例:
1234--0 1243--1 1324--2 1342--3 1423--4 1432--5
2134--6 2134--7 2314--8 2341--9 2413--10 2431--11
3124--12 3142--13 3214--14 3241--15 3412--16 3421--17
4123--18 4132--19 4213--20 4231--21 4324--22 4342--23
如何根据编号来还原得到排列方式呢?以编号15为例:
3!=6 2!=2 1!=1 0!=1
将这些阶乘的结果保留到数组factorialArray[4]中:factorialArray[4]={6,2,1,1}
15%6=3 15/6=2
3%2=1 3/2=1
1%1=0 1/1=1
0%1=0 0/1=0
将除法的商依次保留到数组deleOrderArray[4]中:deleOrderArray[4]={2,1,1,0}
生成链表1->2->3->4
按照deleOrderArray的顺序依次取出其中的元素(注:链表中的索引从0到3,即对于deleOrderArray[0]=2,则应该取出数字3,并将3从链表中删除)
这样就可以得到:3241,就是我们前面提到的编号表中的排列。
已知共有n!个排列方式,可以对这些排列方式编号:0到(n!-1),每个编号唯一地对应一个排列方式。循环地根据每个编号来还原出它所对应的排列方式即可。
如何编号呢?以n=4为例:
1234--0 1243--1 1324--2 1342--3 1423--4 1432--5
2134--6 2134--7 2314--8 2341--9 2413--10 2431--11
3124--12 3142--13 3214--14 3241--15 3412--16 3421--17
4123--18 4132--19 4213--20 4231--21 4324--22 4342--23
如何根据编号来还原得到排列方式呢?以编号15为例:
3!=6 2!=2 1!=1 0!=1
将这些阶乘的结果保留到数组factorialArray[4]中:factorialArray[4]={6,2,1,1}
15%6=3 15/6=2
3%2=1 3/2=1
1%1=0 1/1=1
0%1=0 0/1=0
将除法的商依次保留到数组deleOrderArray[4]中:deleOrderArray[4]={2,1,1,0}
生成链表1->2->3->4
按照deleOrderArray的顺序依次取出其中的元素(注:链表中的索引从0到3,即对于deleOrderArray[0]=2,则应该取出数字3,并将3从链表中删除)
这样就可以得到:3241,就是我们前面提到的编号表中的排列。
#include <stdio.h>
#include <stdlib.h>
#include "SingleList.h"
//#include "Stack.h"
#define N 5
void geneList(int n, List *L);
void geneJch(int n, long a[]);
void geneDeleOrderArray(int n, int num, int deleOrderArray[], int factorialArray[]);
/*
function:generaer a list with data form 1 to n
input:n and List pointer
output:void
*/
\\通过头插法生成链表1->2->3->……->(n-2)->(n-1)->n
void geneList(int n, List *L)
{
int i = 0;
if(L->next != NULL)
{
printf("This list is not empty, and there must be some mistake!\n");
exit(1);
}else
{
for(i = n; i > 0; i --)
{
headInsert(i,L);
}
}
}
/*
function:generator an array which value are (n-1)! to 0!
input:n and array which len is n
output:void
*/
\\计算(n-1)!到0!,将结果依次存放到数组factorialArray[n]中
void geneFactorialArray(int n, int factorialArray[])
{
int i = 0;
int index = 1;
factorialArray[n-1] = 1;
for(i = n-2; i >= 0; i --)
{
factorialArray[i] = factorialArray[i+1] * index;
index ++;
}
}
/*
function:geneYS
input:n,num,a[n]
output:void
*/
void geneDeleOrderArray(int n, int num, int deleOrderArray[], int factorialArray[])
{
int i;
for(i = 0; i < n; i ++)
{
deleOrderArray[i] = num / factorialArray[i];
num = num % factorialArray[i];
}
}
void displayArray(int n, int a[])
{
for(int i = 0; i < n; i ++)
{
printf("%3d",a[i]);
}
printf("\n");
}
int main()
{
/*
List *nList = initList();
int i,j;
int factorialArray[N];
int deleOrderArray[N];
int totalNum = 0;
int perm[N];
geneFactorialArray(N,factorialArray);
totalNum = N * factorialArray[0];
for(i = 0; i < totalNum; i ++)
{
printf("perm num %3d :",i);
geneList(N,nList);
geneDeleOrderArray(N,i,deleOrderArray,factorialArray);
for(j = 0; j < N; j ++)
{
perm[j] = deleElem(deleOrderArray[j],nList);
}
displayArray(N,perm);
}
*/
stack s;
int value = 0;
initStack(&s,5);
push(&s,6);
//pop(&s);
get_top(&s,value);
printf("value = %d\n", value);
return 0;
}