Algorithm of permutation (full ranking algorithm)

Copyright: private individuals do question summed up ~ https://blog.csdn.net/tb_youth/article/details/91349338

STL with a full permutation function next_permutation: Portal

But still write their own relatively good ~

Write your own full array:

#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 105;
int a[MAXN];
int n,cnt;
inline void mySwap(int i,int j)
{
    int temp;
    temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}
inline void print(int *a)
{
    for(int i = 0; i < n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<"\n";
}
/*
全排列递归写法(非字典序)
基本思想:
每次固定该序列的某一个数(固定到s位置),
然后递归调用其他数构成的子序列全排列,
直到需要全排列的子序列只有一个数就打印出整个序列
然后递归返回
*/

//去重
bool check(int cur)
{
    for(int i = cur+1; i < n; i++)//确保只与它后面不相等的数字交换
    {
        if(a[cur] == a[i])
            return false;
    }
    return true;
}

void permutation(int *a,int s)
{
    if(s == n)
    {
        cnt++;
        print(a);
        return;
    }
    for(int i = s; i < n; i++)
    {
        if(check(i))
        {
            mySwap(s,i);
            permutation(a,s+1);
            mySwap(s,i);
        }
    }
}

/*
全排列非递归算法,
并且字典序,
会去重
*/
void permutationTwo(int *a)
{
    sort(a,a+n);
    //第一个要打印出来
    cnt++;
    print(a);
    while(1)
    {
        int pos = -1;
        /*
        从前往后找最后一个:a[i]<a[i+1],pos = i,
        现在从后往前找以提高效率,即转化为
        第一个:a[i] > a[i-1],pos = i - 1;
        */
        for(int i = n-1; i >= 0; i--)//i > 0 防止数组越界
        {
            if(a[i] > a[i-1])
            {
                pos = i - 1;
                break;
            }
        }
        if(pos == -1) break;
        int k = -1;
        /*
        找pos之后最后一个a[i] > a[pos],k = i,
        从后向前找即第一个a[i] > a[pos],k = i
        */
        for(int i = n-1; i > pos; i--)
        {
            if(a[i] > a[pos])
            {
                k = i;
                break;
            }
        }

        //交换pos,k两个位置元素的值
        mySwap(pos,k);
        //反转pos之后元素
        for(int i = pos+1,j = n-1; i <= j; i++,j--)
        {
            mySwap(i,j);
        }
        cnt++;
        //打印permutation
        print(a);
    }
}
int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>a[i];
    }
    cout<<"permutation:"<<endl;
    permutation(a,0);
    cout<<"permutation count = "<<cnt<<endl;
    cnt = 0;
    cout<<"permutationTwo:"<<endl;
    permutationTwo(a);
    cout<<"permutationTwo count = "<<cnt<<endl;
    return 0;
}

Test Results:
Here Insert Picture Description
Here Insert Picture Description

Time complexity:
recursive and non-recursive are approximate O (n!)
, But non-recursive relatively slower, because it in other areas,
such as reverse lookup and so increases the time consumption.

Guess you like

Origin blog.csdn.net/tb_youth/article/details/91349338