用字典顺序得到所有的排列

RT :

为了得到字典顺序的所有排列,我查了一些资料,发现有些说法好像有些问题,现在总结一下;

【字典序法生成全排列】

字典序列算法是一种非递归算法。而它正是STL中Next_permutation的实现算法。我们来看看他的思路吧:
它的整体思想是让排列成为可递推的数列,也就是说从前一状态的排列,可以推出一种新的状态,直到最终状态。比如说,最初状态是12345,最终状态是54321。其实我觉得这跟我们手动做全排列是一样的。首先是12345,然后12354,然后12435,12453....逐渐地从后往前递增。
看看算法描述:
    首先,将待排序列变成有序(升序)序列。然后,从后向前寻找,找到相邻的两个元素,Ti<Tj,(j=i+1)。如果没有找到,则说明整个序列已经是降序排列了,也就是说到达最终状态54321了。此时,全排列结束。

    接着,如果没有结束,从后向前找到第一个元素Tk,使得Tk>Ti(很多时候k=j),找到它,交换Ti跟Tk,并且将Tj到Tn(Tn是最后一个元素)的子序列进行倒置操作。输出此序列。并回到第二步继续寻找ij.
例如839647521是数字1~9的一个排列。从它生成下一个排列的步骤如下:
自右至左找出排列中第一个比右边数字小的数字4    839647521
在该数字后的数字中找出比4大的数中最小的一个5    839647521
将5与4交换 839657421
将7421倒转 839651247
所以839647521的下一个排列是839651247。
839651247的下一个排列是839651274。

这里边的重点或者说是中心思想应该是:

1:两次查找--->分别得到要交换的Ai和Aj

2:两次交换----->第一次是将Ai和Aj 交换位置;

                        第二次是将下标为 i 到 最后的各个元素交换(两头互换)

用字典顺序得到所有的排列_第1张图片

具体代码如下:

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 5 int gArray[MAX_SIZE] = {0}; int gResult[MAX_SIZE] = {1, 2, 3, 4, 5}; void Test() { int nCount = 24; while (nCount > 1) { int i = MAX_SIZE; int j = MAX_SIZE; int k = MAX_SIZE; memset(gArray, 0, sizeof(int)*MAX_SIZE); while(gResult[i - 1] > gResult[i]) { i--; if (1 == i) { break; } } while (gResult[i - 1] > gResult[j]) { j--; if (i == j) { break; } } int nTemp = gResult[i - 1]; gResult[i - 1] = gResult[j]; gResult[j] = nTemp; int m = MAX_SIZE - 1; while (1) { if (m == i) { break; } nTemp = gResult[i]; gResult[i] = gResult[m]; gResult[m] = nTemp; i++; m--; if (i >= m) { break; } } for (k = 0; k < MAX_SIZE; ++k) { printf("/t%d", gResult[k]); } printf("/n"); nCount--; } } int main() { Test(); return 0; }

 

你可能感兴趣的:(算法,permutation)