组合对象,即排列、组合和给定集合的子集等。
数学中我们也学过排列组合,对于给定的一个集合,给出其对应的排列组合,以及对应的子集。
生成排列
排列问题指的是对于给定的多个元素求其中各种可能的序列。为了简单起见,这里仅仅考虑1到n之间的整数的排列问题。
生成排列的方法有三种:插入法、Johnson-Trotter法、字典顺序法
插入法
方法便是依次从集合中取元素,并将其插入到之前生成的排列中。
如:
求n=3的排列
则首先在n=1的排列中插入2,然后在n=2的排列中插入3。
过程便是:
在 1 中从右到左插入2得到 12,21
在 12 中从右到左插入3得到 123,132,312
在 21 中从右到左插入3得到 213,231,321
Johnson-Trotter法
Johnson-Trotter法并不需要知道规模n-1的排列就可以直接得到规模n的排列结果。利用这一算法求得的排列序列还是相邻序列变化最小的一个序列集合,也就是说下一个序列与上一个序列仅仅交换了两个元素的位置。
方法便是:
在排列的每一分量上画一个箭头。
可移动元素:如果分量k的箭头指向一个相邻的较小元素,则该分量在排列中是可移动的。
步骤一:找到当前最大的可移动整数k,移动此元素,掉转所有大于k 的整数方向。
重复步骤一,直到没有可移动的元素为止。
开始排列123首先初始化为向左,然后马上就能够确定3为最大的可移动整数,因此得到132的排列,进而得到312。
注意此时最大的可移动整数变为了2,所以应该开始移动元素2,得到321,并将3的箭头调转,
之后最大的可移动整数又变为了3,移动之后得到231,进而得到213,
注意到,此时的排列已经找不到一个可移动的整数了,因此算法结束
可以看到,Johnson-Trotter法确实能够一遍就得到所有的排列,但是我们也同时能够发现这样生成的排列并不符合我们的思维习惯,因此便有了比较自然的字典排序算法
。
字典排序算法
对于n=3,
按字典顺序生成的序列为123、132、213、231、312、321