| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3723 人关注过本帖, 2 人收藏
标题:【木有人?】递归全排列问题
只看楼主 加入收藏
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
结帖率:97.44%
收藏(2)
已结贴  问题点数:20 回复次数:19 
【木有人?】递归全排列问题
程序代码:
#include"stdio.h"
#define SWAP(a,b,c) ((c)=(a),(a)=(b),(b)=(c))

void perm(int *list,int i,int n);
int main()
{
    int arry[4]={1,2,3,4};
    perm(arry,0,3);
    return 0;
}

void perm(int *list,int i,int n)
{
    int j,temp;
    if(i==n)
    {
        for(j=0;j<=n;j++){
            printf("%d",list[j]);
        }
        printf("\n");
    }
    else
    {
        for(j=i;j<=n;j++){
            SWAP(list[i],list[j],temp);
            perm(list,i+1,n);
            SWAP(list[i],list[j],temp);
        }
    }
}

当递归与循环在一起的时候,我就晕了!有人能解释下这个算法吗?还有个问题,递归到了终止条件之后是怎么样返回的?
木有人回答?那我先分析一下!

首先,排列要得到1,2,3,4的全排列,只需要先以1开头,把2,3,4全排列,要把2,3,4进行全排列,只需要以2开头,全排列3,4,对3,4进行全排列,则以3开头,对4全排列
                                              2        1,3,4                                     3            2,4                        4        3
                                              3        1,2,4                                     4            2,3
                                              4        1,2,3


在上面,蓝色部分就是利用递归,紫红色部分就是利用循环

那就先以1开头进行递归求出以1开头的全排列 分析


for(j=0;j<=3;j++)    i=0    <--------第一次调用perm

    交换list[0],list[0] | list[0],list[1] | list[0],list[2] | list[0],list[3]

        for(j=1;j<=3;j++)  i=1 <------第二次调用

            交换list[1],list[1] | list[1],list[2] | list[1],list[3]

                for(j=2;j<=3;j++) i=2 <----第三次调用

                    交换list[2],list[2] | list[2],list[3]

                        for(j=3;j<=3;j++) i=3          <-----满足递归终止条件i=n=3

                            交换list[3],list[3]        <-----输出:1 2 3 4    返回上一级函数  请问返回上一级函数,上一级函数所执行的操作!





希望没有分析错误吧!

[ 本帖最后由 liangjinchao 于 2011-5-9 22:50 编辑 ]
搜索更多相关主题的帖子: color 
2011-05-08 17:06
huwengui
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:166
专家分:158
注 册:2011-4-22
收藏
得分:0 
这个程序的意思就是
输出arry[4]={1,2,3,4}中数据所有组合
比如:
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2431 2413
.
.
.
2011-05-08 18:29
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
兄弟,这个我知道!我是要这算法的意思,而不是这程序的意思!

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-08 19:23
laoyang103
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:内蒙古包头
等 级:贵宾
威 望:19
帖 子:3082
专家分:11056
注 册:2010-5-22
收藏
得分:0 
好难懂  我也弄不太明白

但是我知道下面的else递归的目的是使得数组

中的元素有和前面的所有排列都不一样的排列

这样它的递归边界就是得到了这个和前面都不一样的排列

然后就返回  但是要打印多个排列  就要循环了

个人理解  我实在是看不懂   抱歉

                                         
===========深入<----------------->浅出============
2011-05-08 19:44
molin
Rank: 1
等 级:新手上路
帖 子:16
专家分:5
注 册:2010-4-17
收藏
得分:0 
    if(i==n)
    {
        for(j=0;j<=n;j++){
            printf("%d",list[j]);
        }
        printf("\n");
    }
这里看不懂什么意思
2011-05-09 13:42
molin
Rank: 1
等 级:新手上路
帖 子:16
专家分:5
注 册:2010-4-17
收藏
得分:0 
i和n相等时表示什么意思?
2011-05-09 13:43
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
回复 6楼 molin
是递归的终止条件!

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-09 18:09
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
我顶,顶,顶到有人回答为止!

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-09 22:51
张彬彬
Rank: 2
等 级:论坛游民
帖 子:17
专家分:10
注 册:2011-4-25
收藏
得分:0 
回六楼
就是比较的意思吗?
2011-05-09 23:38
诸葛修勤
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:11
帖 子:549
专家分:1955
注 册:2010-10-28
收藏
得分:20 
这程序写的很好啊

#include"stdio.h"

#define SWAP(a,b,c) {(c)=(a); (a)=(b); (b)=(c);}

void perm(int *list,int i,int n);

int main()
{
    int arry[5]={1,2,3,4,5};
    perm(arry,0,4);

    return 0;
}

void perm(int *list,int i,int n)
{
    static int counter;
    int j,temp;
    if(i==n)
    {//当n个数排列好之后 进行打印   
        printf("%d\t", ++counter);
        for(j=0; j<=n; j++)
        {//这里是循环打印一个数组  的长度 下标从零开始 到 n(长度减一)
            printf("%d", list[j]);
        }

        printf("\n");
    }
    else
    {
        for(j=i;j<=n;j++)
        {
            1)SWAP(list[i],list[j],temp);
            2)perm(list,i+1,n);
            3)SWAP(list[i],list[j],temp);//这里的三句用的很好  不知道是谁写的 有点喜欢他啦  这里和中断的机制极为相像
                                          //首先1)可以理解成是现场保护为 这只是从结构上说 实际上这里 就相当于中断服务程序啦 即你实际要做的事情啦
                                          //2)这里可以理解为中断嵌套 即进入下一个中断 也就是说下一级的中断的优先级比上一级的高 所以先得以运行
                                          //3)这里就是现场恢复啦  实际上做的事情的确是把交换后的两个数据的再次交换 恢复到交换之前的状态 即1)状态之前
        }
    }
}

每当进入else的时候 j的初始状态值是设置为i的 所以进入for中第一次的交换是自身和自身交换 原程序运行的是一句逗号表达式


2011-05-10 00:26
快速回复:【木有人?】递归全排列问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019790 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved