全排列的两种递归实现

版权声明:本文为博主原创文章,欢迎交流学习,未经博主允许不得转载。 https://blog.csdn.net/qq_43749739/article/details/88046551

一、什么是全排列

(我是懒癌)
关于N的全排列即,从1开始至N,N个数的全部排列方式。
如:关于3的全排列:
1 2 3;1 3 2;2 1 3;2 3 1;3 1 2;3 2 1;

二、思路一

func()的参数是将要赋值给数组P[]的数字,P[]存储全排列序列,cnt为数组下标,Hash[]=0为该数字未出现过,Hash[]=1位该数字已在P[]中;
有点讲不清,大家凑合看下代码注释_(:з」∠)_在这里插入图片描述

#include <stdio.h>
int N,Hash[100]={0},P[100],cnt=0;
void func(int k)//k为将要赋值给P[cnt]的值
{
    P[cnt++]=k;//赋值给P[]
    Hash[k]=1;//编辑k值已经使用过,不再出现;
    if( cnt == N )//若P[]中已经有N个数,输出;
        for(int i=0 ; i<N ; i++)
            printf("%d%s",P[i],i==N-1 ? "\n":" ");
    else//否则选择下一个未出现过的数赋值给P[];
        for(int i=1 ; i<=N ; i++)
            if( !Hash[i] )
                func(i);
    cnt--;//P[]的数组指针后退一位;
    Hash[k]=0;使k重新可用;
    return;
}func(k)输出所有以k为第一个数字的全排列;因此main()中要从1至N,func(i);
int main()
{
    scanf("%d",&N);
    for(int i=1 ; i<=N ; i++)
        func(i);
}

三、思路二

func()的参数是P[]的数组下标(不再用cnt),功能是选择一个合适的值输入全排列序列P[],或输出;Hash[]功能同思路一;

#include <stdio.h>
int N,Hash[100]={0},P[100];
int func(int n)//对P[n]赋值从1开始第一个未赋值过的数;
{
    if(n == N)//n等于N时,输出数组;
        for(int i=0 ; i<N ; i++)
            printf("%d%s",P[i],i==N-1 ? "\n":" ");
    else//否则找出从1开始第一个未赋值过的数字;
        for(int i=1 ; i<=N ; i++)//从1至N遍历;
            if( !Hash[i] )//Hash[i]==0:i未赋值过;
            {
                P[n]=i;//赋值
                Hash[i]++;//标记赋值过,不再使用;
                func(n+1);//对P[]的下一位处理
                Hash[i]--;//返回后取消i的赋值过标记,
            }
}
int main()
{
    scanf("%d",&N);
    func(0);
}

猜你喜欢

转载自blog.csdn.net/qq_43749739/article/details/88046551
今日推荐