全排列算法的c++实现(非递归)

本文算法出自:梦辽软件,只实现了文中所说的第五种算法

/*  
全排列(非递归求顺序)算法  
1、建立位置数组,即对位置进行排列,排列成功后转换为元素的排列;  
2、按如下算法求全排列:  
设P是1~n(位置编号)的一个全排列:p = p1,p2...pn = p1,p2...pj-1,pj,pj+1...pk-1,pk,pk+1...pn  
(1)从排列的尾部开始,找出第一个比右边位置编号小的索引j(j从首部开始计算),即j = max{i | pi < pi+1}  
(2)在pj的右边的位置编号中,找出所有比pj大的位置编号中最小的位置编号的索引k,即 k = max{i | pi > pj}  
   pj右边的位置编号是从右至左递增的,因此k是所有大于pj的位置编号中索引最大的  
(3)交换pj与pk  
(4)再将pj+1...pk-1,pk,pk+1...pn翻转得到排列p' = p1,p2...pj-1,pj,pn...pk+1,pk,pk-1...pj+1  
(5)p'便是排列p的下一个排列  
 
例如:  
24310是位置编号0~4的一个排列,求它下一个排列的步骤如下:  
(1)从右至左找出排列中第一个比右边数字小的数字2;  
(2)在该数字后的数字中找出比2大的数中最小的一个3;  
(3)将2与3交换得到34210;  
(4)将原来2(当前3)后面的所有数字翻转,即翻转4210,得30124;  
(5)求得24310的下一个排列为30124。  
*/ 
#include <iostream>
using namespace std;
template<class T>
void print(T* arr,int len) {
    int i   = 0;
    while(i < len)
    {
        cout<<arr[i]<<"\t";
        i++;
    }
    cout<<endl;
}
template<class T>
void swap(T* arr,int i,int j) {
    T t   = arr[i];
    arr[i]  = arr[j];
    arr[j]  = t;
}
template<class T>
bool sort(T* arr,int len) {
    int j;
    for (j = len - 2; j >= 0 && arr[j] > arr[j + 1]; j--)
    //本循环从位置数组的末尾开始,找到第一个左边小于右边的数的位置,即j
        ;
    if (j < 0)
        return false; //已完成全部排列
    T tmp = arr[j];
    int index = -1,k;
    for (k = len - 1; k > j; k--)
    //即找出索引j右边的数中所有大于arr[j]元素中的最小元素的索引
    {  
        if(tmp != arr[j] && arr[k] > arr[j] && arr[k] < tmp)
        {
            tmp     = arr[k];
            index   = k;
        }
        else if(tmp == arr[j] && arr[k] > tmp)
       {
           tmp      = arr[k];
           index    = k;
       }
    }
    swap(arr, j, index);
    for (j = j + 1, k = len - 1; j < k; j++, k--)
        //本循环翻转j+1到末尾的所有位置
        swap(arr, j, k);
    return true;
}
int main(int argc,char* argv[])
{  
    int     times = 0;
    char    elem[] = {'z','q','f','t','2'};//要进行全排列的元素
    int     index[5] = {0,1,2,3,4};//元素的索引,0对应'z',.....,4对应'2'
    do {
        char    tmp[5];
        int     i = 0;
        while(i < 5)
        {
            tmp[i] = elem[index[i]];
            i++;
        }
        print(tmp,5);
        print(index,5);
        times++;
    } while (sort(index,5));
    cout<<"=====\t"<<times<<"\t====="<<endl;
    return 0;
}


你可能感兴趣的:(C++,全排列)