生成n个数的排列的算法

/*	生成{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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值