下一个排列

下一个排列
昨天在《算法竞赛入门经典》中,挺刘汝佳介绍了C++的标准库中有“求一个数字序列的下一个排列”的函数,然后自己思考了一下如何实现这个函数。
所谓下一个排列,比如对于序列1 2 3,它的下一个排列是1 3 2,再下一个是2 1 3……
首先想到的是通过一种规律性的总结,找到一种递推或者其他方法,对原序列做相应的变换,求得下一个排列。但是经过大约十分钟的思考之后,发现这种办法似乎行不通。
后来仔细地回忆了求全排列的过程,有了这么一个思路:之所以不能够直接求得下一个排列,就是因为不知道此时dfs()运行的情况,如果直接让dfs()运行到当前的情况,问题迎刃而解。
于是便有了下面的代码:
#include < stdio.h >
const   long  maxn = 108 ;
long  n,a[maxn];
bool  used[maxn],first,ans;
void  dfs( long  dep)
{
    
if (dep > n)
    {
       
if (first) first = false ;
       
else
       {
          
bool  f = true ;
          
for ( long  i = 1 ;i <= n;i ++ )
          {
             
if (f) f = false ;
             
else  putchar( '   ' );
             printf(
" %ld " ,a[i]);
          }
          putchar(
' \n ' );
          ans
= true ;
       }
       
return ;
    }
    
for ( long  i = 1 ;i <= n &&! ans;i ++ )
      
if (first)
      {
         i
= a[dep];
         dfs(dep
+ 1 );
         used[i]
= false ;
      }
      
else   if ( ! used[i])
      {
         used[i]
= true ;
         a[dep]
= i;
         dfs(dep
+ 1 );
         used[i]
= false ;
      }
}
int  main()
{
    
// *
    freopen( " program.in " , " r " ,stdin);
    freopen(
" program.out " , " w " ,stdout);
    
// */
    n = 0 ;
    
while (scanf( " %ld " , & a[n + 1 ]) == 1 ) n ++ ;
    
//   Read In
    ans = false ;
    first
= true ;
    
for ( long  i = 1 ;i <= n;i ++ ) used[i] = true ;
    dfs(
1 );
    
if ( ! ans) printf( " No answer\n " );
return   0 ;
}
这段代码只适用于1-n不重复数字的排列,如果数字同样不重复,修改为任意一些数字的排列问题也是十分简单的。

你可能感兴趣的:(下一个排列)