算法02:全排列字典序算法

全排列递归算法http://blog.csdn.net/u014599786/article/details/23170749

(2)字典序法

对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。如{1,2,3}的排列中,132排在123之后,排在213之前。


算法思路:

1.如对于{1,2,3,4,5}的一个排列p1为list[]={1,3,4,6,5,2},要求出下一个排列,首先要从最右边开始,向左找到第一个左边的数小于右边的数的位置i,在p1中为46即i=2号位置(下标从0开始);

2.再从最右边开始,找到比list[i]大的数中最小者的位置j,因为list中的数是按字典序排序的,所以list[i]以后的数组元素是从大到小排列的,所以j即为从最右边开始第一个比list[i]大的数的下标,p1为5中j=4;

3.交换list[i]、list[j]后list[]={1,3,5,6,4,2},此时5后面的数是从从大到小排列的,所以按字典序的下一个排列应该把后面的数倒转,既得到下一个排列list[]={1,3,5,2,4,6}


完整算法:

#include <cstdlib>
#include <iostream>

using namespace std;

int list[100], n;

//交换数组两个元素 
void swap(int i, int j)
{
     int temp;
    
     temp = list[i];
     list[i] = list[j];
     list[j] = temp;
}

//将数组逆序 
void reverse_list(int i)
{
     int j, k;
     for(k = i+1, j = n-1; j > k; j--, k++)
             swap(j, k);
}

//输出数组 
void print_list()
{
     for(int i = 0; i < n; i++)
             cout<<list[i]<<" ";
         cout<<endl; 
}

//按字典序输出全排列 
void next_perm()
{
      int i, j, total = 0;
      
      if(n == 1){
         print_list();
         return;
      }
      
      while(1){
            print_list();
            total++;
            
            //从最右边开始,找第一个左边小于右边的数的位置 
            for(i = n-2; i >= 0; i--)
                if(list[i] < list[i+1]) break;
                
            // 没有逆序对结束 
            if(i < 0) break;
          
            //从最右边开始,找到第一个比list[i]小的数 
            for(j = n-1; j > i ;j--)
               if(list[j] > list[i]) break;
            
            swap(j, i);
               
            //将位置i后面的数组元素逆序 
            reverse_list(i);
     }
     
     cout<<total<<endl;
}

int main()
{  
    while(cin>>n){
          for(int i = 0; i < n;)
             list[i] = ++i; 
    
          next_perm();    
    }
    
    system("PAUSE");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值