| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3723 人关注过本帖, 2 人收藏
标题:【木有人?】递归全排列问题
取消只看楼主 加入收藏
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
结帖率:97.44%
收藏(2)
已结贴  问题点数:20 回复次数:7 
【木有人?】递归全排列问题
程序代码:
#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
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
兄弟,这个我知道!我是要这算法的意思,而不是这程序的意思!

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-08 19:23
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
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
程序代码:
以下是引用诸葛修勤在2011-5-10 00:26:23的发言:

这程序写的很好啊

#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(长度减一)  //为什么n会减一呢?n不是一直都是4吗?所以始终会打印数组中5个元素出来!
            printf("%d", list[j]);
        }

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

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



因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-10 08:00
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
回复 11楼 诸葛修勤
再请教几个问题,函数满足递归终止条件,然后输出1,2,3,4,5 对吧?然后返回到上一级对4,5进行全排列,那么返回到上一级的时候,函数的执行顺序是从头开始执行直到结束,还是执行递归入口后面的语句?返回上一级的时候,i是不是相应减一?

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-10 08:10
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
回复 12楼 夜叶
再难也要学下去!

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-10 08:14
liangjinchao
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:376
专家分:697
注 册:2010-11-8
收藏
得分:0 
回复 17楼 于祥

因为有了因为,所以有了所以,既然已成既然,何必再说何必
2011-05-10 12:43
快速回复:【木有人?】递归全排列问题
数据加载中...
 
   



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

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