c语言排列算法已有代码看不懂求分析

2022-04-02 科技 64阅读
可以这样理解:假如要求序列12345的排列数,那么perm(list,k,m)中的k就是0,m就是4(都是指的下标),也就是说求list数组中第一个数到第五个数的排列数。
12345的排列数可以递归的拆成五部分,第一部分、第一个数取1,然后求后四个数2345的排列数,第二部分、第一个数取2,然后求后四个数1345的排列数,第三部分、第一个数取3,然后求后四个数1245的排列数,第四部分、第一个数取4,然后求后四个数1235的排列数,第五部分、第一个数取5,然后求后四个数1234的排列数。这是第一轮递归拆分,然后上面的五部分都可以再进行递归拆分,每个部分可以拆成第一个数和后三个数,然后再对后三个数进行全排列,这样一直递归的拆分,直到求perm(list,4,4)即一个数的的全排列,就是它本身,说明全排列已经生成,打印出此时list中的值即可。

对应代码中对应的步骤为:

if(k==m){//m=k说明要求的全排列只有一个数,此时list已经存放了一次全排列的值,输出即可
for(i=0;i<=m;i++)
printf("%c",list[i]);
putchar('\n');
}

else//m!=k的话,说明list中k到m的元素还可以递归拆解
for(i=k;i<=m;i++){//for循环进行递归拆解
Swap(list[k],list[i]);//list[k]是当前要拆解的全排列中的第一个数,它每次和从k到m中的某个数list[i]交换,让list[i]成为第一个数,然后递归的求从k+1位置到m位置的全排列。

Perm(list,k+1,m);
Swap(list[k],list[i]);//求完了一次全排列,要把list[k]还原为第一个数,以进行下次for循环。
}

不知道我解释的明不明白,不明白可以继续问。
声明:你问我答网所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系fangmu6661024@163.com