排列生成算法--字典序法

本文地址:http://blog.csdn.net/spch2008/article/details/9631943


所谓字典序法就是按照字典排序的思想逐一产生所有排列。比如1,2,3,4四个数字进行全排列,先1234,1243,1324,1342,1423,1432,…4321。

由1243生成1324的过程:

1. 1243从右向左找第一个正序对24

2. 从右向左找第一个大于2的数,3

3. 交换2与3的位置的:1342

4. 把3后面的数字全部反序的:1324


总结:

1. 从右向左找到第一个正序Pi < Pi+1 (i+1为下标)

2. 从右向左找到第一个大于Pi的数Pj

3. 交换Pi与Pj

4. 将Pj后面的数全部反序,得到一个排序


代码:

void swap(int *arr, int i, int j)
{
	int tmp = arr[i];
	arr[i]  = arr[j];
	arr[j]  = tmp;
}


void reverse(int *arr, int first, int last)
{
	while( first != last && first != --last)
	{
		swap(arr, first, last);
		first++;
	}
}

//true   数组元素顺序改变
//false  数组元素顺序没有改变
bool permutation(int *arr, int N)
{
	if(N == 0 || N == 1)
		return false;

	int last = N;
    //ii代表i-1
	int ii = last - 1;
	int i  = ii - 1;

	while(true)
	{	
		if(arr[i] < arr[ii])
		{
			int j = last - 1;
			while( !(arr[i] < arr[j]) )
				j--;
		
			swap(arr, i, j);
			//i位置后(不包含i)元素逆序
			reverse(arr, ii, last);
			return true;
		}
		//已是递减排序,无下一个排序了。
		if(i == 0)
		{
			//全部倒序,恢复最初状态
			reverse(arr, i, last);
			return false;
		}
		i--; ii--;
	}
}

int main()
{
	int arr[] = {1,2,3};
	int size  = sizeof(arr) / sizeof(int);

	for(int i = 0; i < size; i++)
		cout << arr[i] << " ";
	cout << endl;
	while(permutation(arr, size))
	{
		for(int i = 0; i < size; i++)
			cout << arr[i] << " ";
		cout << endl;
	}
	

	system("pause");
	return 0;
}

结果:

排列生成算法--字典序法_第1张图片


你可能感兴趣的:(排列生成算法--字典序法)