C语言求一个序列的字典序排序


给出正整数n,则1~n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1 这6个排列。 

字典序算法如下:

假设这n个数的某一个排列为 P: P1 P2 P3...Pj-1 Pj Pj+1...Pk-1 Pk Pk+1...Pn

1.从该序列的最右端开始向左找出第一个比与自己相邻的右边数小的数,记其下标为j,即j = max{i|Pi<pi+1}.

2.找出Pj右边比Pj大的最小数Pk.

3.交换Pj,Pk.此时序列变为 P’: P1 P2 P3...Pj-1 Pk Pj+1...Pk-1 PPk+1...Pn

4.将Pj+1...Pn 倒转,即得到此序列的后一个序列 P”: P1 P2 P3...Pj-1 Pn...Pk+1 PPk-1...Pj+1

例:

1 2 3 5 7 4 6 10 9 8为1-10的一个排列

1.从该序列的最右端开始向左找出第一个比与自己相邻的右边数小的数6,其下标为7

2.6右边比6大的最小数为8

3.交换6,8得到1 2 3 5 7 4 8 10 9 6

4.将P8-P10倒转得到:1 2 3 5 7 4 8 6 9 10即为下一个序列;

部分代码如下:

void sort(int n[], int num)//首先进行排序求出第一个字典序
{
	int temp;
	for (int i = 0; i < num ; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (n[j]>n[j + 1])
			{
				temp = n[j];
				n[j] = n[j + 1];
				n[j + 1] = temp;
			}
		}
	}
}
void flip(int n[], int a, int b)
{
	int temp;
	for (int i = a, j = b; i < j; i++, j--)
	{
		temp = n[i];
		n[i] = n[j];
		n[j] = temp;
	}
}
void order(int n[], int num)
{
	int index1;
	int index2;
	for (int i = num - 1; i >= 0; i--)
	{
		if (n[i - 1] < n[i])
		{
			index1 = i-1;
			break;
		}
	}
	int temp;
	int j;
	for ( j = index1+1; j < num; j++)
	{
		if (n[j]>n[index1])
		{
			temp = n[j];
			index2 = j;
			break;
		}
	}
	for (int k = j+1; k < num; k++)
	{
		if ((n[k]>n[index1]) && (n[k]<n[index2]))
		{
			index2 = k;
		}
	}
	temp = n[index1];
	n[index1] = n[index2];
	n[index2] = temp;
	//for (int i = 0; i < 10; i++)
	//{
	//	printf("%d\t", n[i]);
	//}
	flip(n, index1 + 1, num - 1);
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值