/* 生成{1,2,3,……,n}的排列的算法*/
#include<stdio.h>
#define FALSE 0
#define TRUE 1
#define B 0
#define F 1
#define N 4
typedef int dir;
//用于存放数据的结构体
typedef struct num{
int data; //数据域
dir dt; //移动方向
int ismove; //是否可以移动
}mynumber;
void print(mynumber a[],int n);
void fun(mynumber a[],int n);
//计数器
int cot;
void main()
{
int i;
//用于存放数据的数组
mynumber arr[N];
//对计数器和数组初始化
cot = 0;
for(i = 0;i < N; ++i)
{
arr[i].data = i + 1;
arr[i].dt = B;
if(0 == i)
arr[i].ismove = FALSE;
else
arr[i].ismove = TRUE;
}
//先打印一次
print(arr,N);
//调用fun()函数生成排列
fun(arr,N);
printf("共%d种排列\n",cot);
}
//交换两个结构体的函数
void change(mynumber *a,mynumber *b)
{
mynumber temp;
temp = *a;
*a = *b;
*b = temp;
}
//求出可移动的最大的数的脚标,不存在时返回-1
int max(mynumber a[],int n)
{
int i,k;
k = -1;
//找到第一个可移动的数
for(i = 0;i < n; ++i)
{
if(a[i].ismove)
{
k = i;
break;
}
}
//找到最大的可移动的数
for(i = k;i < n; ++i)
{
if(a[i].ismove)
if(a[i].data > a[k].data)
k = i;
}
return k;
}
//打印函数
void print(mynumber a[],int n)
{
int i;
for(i = 0;i < n; ++i)
{
printf("%d ",a[i].data);
/*if(B == a[i].dt)
printf("B ");
else printf("F ");
if(TRUE == a[i].ismove)
printf("Y ");
else printf("N ");*/
}
printf("\n");
//计数器加1
cot++;
}
//排列函数
void fun(mynumber a[],int n)
{
int i,m,next;
m = max(a,n);
//当没有可移动的数时直接返回
if(-1 == m)
return;
//根据数据的移动方向移动数据
if(B == a[m].dt)
next = m - 1;
else
next = m + 1;
change(&a[m],&a[next]);
print(a,n); //每移动一就打印一次
//校正数据的可移动性和移动方向
for(i = 0;i < n; ++i)
{
//改变所有大于当前可移动最大数的移动方向
if(a[i].data > a[next].data)
if(B == a[i].dt)
a[i].dt = F;
else
a[i].dt = B;
//校正数据的可移动性
if(B == a[i].dt) //第i + 1个数的移动方向向时
{
if(0 == i) //第一个数不可再移动
a[i].ismove = FALSE;
else //当前一个数小于第i + 1个数时,第i + 1个数才可以移动
if(a[i - 1].data > a[i].data)
a[i].ismove = FALSE;
else a[i].ismove = TRUE;
}
else //第i + 1个数的移动方向向前时
{
if(n - 1 == i) //最后一个数不可再移动
a[i].ismove = FALSE;
else //当后一个数小于第i + 1个数时,第i + 1个数才可以移动
if(a[i + 1].data > a[i].data)
a[i].ismove = FALSE;
else a[i].ismove = TRUE;
}
}
//递归调用fun()函数,直到没有可移动的数据
fun(a,n);
}
生成n个数的排列的算法
最新推荐文章于 2022-03-04 18:49:57 发布