下一次全排列结果

下一次全排列结果

    上一篇文章我写的全排列的方法,那么如果给定一组排列好的数字,例如“12453”,那么下一次按照一般思路做下一次排列将会得到什么样的结果呢?

    我们知道,接照一般思路来说,一组数“123456”,下一次我们会将6和5作交换,即得“123465”,接着再对倒数第三个数进行操做,将5和6中较小的数,即5放到倒数第三个位置上,再把4和6按升序排列,即得“123546”。

    按照这个方法我们就能得到“12453”的下一次排列结果。

              A. 定义一个变量nDropPos来保存第一个降序数的下标, 同时定义另一个变量n_pos保存从右到左的第一个比降序数大的下标

    B. 判断降序数位置及大小,若降序数下标为-1,则不作处理。

      若降序数出现在倒数第二个位置,则交换两个数。若降序数大于nDropPos-2,则交换降序数与nDropPos-1下标的数。

      否则将该降序数与n_pos下标的数交换,并从nDropPos+2下标开始一直到strlen(s) -1结束,进行除序排序。代码如下所示:




#include <iostream>
#include <string.h>
using namespace std;
#define exchange(x, y) {int temp = x; x = y; y = temp;}
const int N = 8;
int index[N] = {0, 1, 2, 3, 4, 5, 6, 7};//排列数


void sort(int *p, int beg, int end)
{//冒泡排序
	int i = 0;
	for(; end > beg; end --)
		for(i = beg; i < end; i++)
			if(*(p + i) > *(p + i + 1))
				exchange(*(p + i), *(p + i + 1));
}

void print()
{//打印结果
	int i = 0;
	for(i = 0; i < N; i++)
		cout << index[i] << " ";
	cout << endl;
}

void next_permutation(int* cur, int n)
{//得到下一次全排列
	int i = 0, decIndex = n- 1, excIndex = n - 1, temp = 0;


	if(cur[n - 1] > cur[n - 2])
	{
		exchange(cur[n - 1], cur[n - 2]);
		print();
		return;
	}

	for(i = n - 1; i > -1; i --)
	{
		if(*(cur + i) > *(cur + i - 1))
		{
			decIndex = i - 1;//得到第一个降序数
			break;
		}
	}
	if(decIndex == -1)
		return;

	temp = cur[decIndex];
	for(i = decIndex + 1; i < n; i++)
	{//得到要交换的数
		if(cur[i] > temp)
			temp = cur[i];
		if(cur[i] > cur[decIndex] && cur[i] <= temp)
			excIndex = i;
	}

	exchange(cur[decIndex], cur[excIndex]);
	sort(cur, decIndex + 1, n - 1);

	print();
}


int main()
{

	int n = 0, resu = 0;
	for(n = 0; n < 24; n++)//循环做下一次全排列
		next_permutation(index, 4);//index为当前排列,4为要排列的元素个数
	system("pause");
	return 0;
}

 

点赞