关于排列算法中,递归的问题

lihan6415151528 2009-10-17 11:30:03
代码如下:

// test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

#include <stdio.h>

int n = 0;
void swap(int *a, int *b)
{
int m;
m = *a;
*a = *b;
*b = m;
}
int z = 0;
//m为整数数组结束位置
void perm(int list[], int k, int m)
{
z++;
int i;
if(k > m)
{
for(i = 0; i <= m; i++)
printf("%d ", list[i]);
printf("\n");
n++;
}
else
{
for(i = k; i <= m; i++)
{
swap(&list[k], &list[i]);
perm(list, k + 1, m);
swap(&list[k], &list[i]);//这句去掉之后运行结果一样
}
}
}
int main()
{
int list[] = {1, 2, 3, 4, 5};
perm(list, 0, 4);
printf("total:%d\n", n);
cout<<z;
return 0;
}



不太理解在循环中再次调用递归程序跑的流程,特此问一下,这个程序是如何实现的

另外,我在关键之处插入断点,发现执行到第五次时候,即K=5时,执行完if语句块,又直接跳到else语句块里面的for循环中的perm(list, k + 1, m); 这里了即递归这里。 很是费解。 ,求高人指点
...全文
166 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
baihacker 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lihan6415151528 的回复:]
引用 2 楼 baihacker 的回复:
void perm(int list[], int k, int m)
的意思在于对list的第k到第m个数进行排列.
当k=m的时候显然就不用了.
否则的话,把第i(k <=i <=m)个数取出来,作为这个排列的头.
后面的再进行排列.
你的第一个swap就是把第i个取出来.
当然,取了之后,还要恢复状态啊,第二个就是恢复.

perm(list, 1, 4); 那样的话就是只排列 2,3,4,5了?
但情况并不是这样,
关键是没有解释清楚我遇到的断点里面走的那种情况呢
这才是我最想知道的
还是希望老胸帮忙仔细解释一下,谢了
[/Quote]
怎么不是只排列2 3 4 5

1 2 3 4 5
1 2 3 5 4
1 2 4 3 5
1 2 4 5 3
1 2 5 4 3
1 2 5 3 4
1 3 2 4 5
1 3 2 5 4
1 3 4 2 5
1 3 4 5 2
1 3 5 4 2
1 3 5 2 4
1 4 3 2 5
1 4 3 5 2
1 4 2 3 5
1 4 2 5 3
1 4 5 2 3
1 4 5 3 2
1 5 3 4 2
1 5 3 2 4
1 5 4 3 2
1 5 4 2 3
1 5 2 4 3
1 5 2 3 4
total:24
65
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
当k==5时,进入到if(k>m){}中执行,接着调用结束,返回到上一层,而上一层是在else{}中,所以又回到perm后的一条语句swap,就这样递归直到结束。
lihan6415151528 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 baihacker 的回复:]
void perm(int list[], int k, int m)
的意思在于对list的第k到第m个数进行排列.
当k=m的时候显然就不用了.
否则的话,把第i(k <=i <=m)个数取出来,作为这个排列的头.
后面的再进行排列.
你的第一个swap就是把第i个取出来.
当然,取了之后,还要恢复状态啊,第二个就是恢复.
[/Quote]
perm(list, 1, 4); 那样的话就是只排列 2,3,4,5了?
但情况并不是这样,
关键是没有解释清楚我遇到的断点里面走的那种情况呢
这才是我最想知道的
还是希望老胸帮忙仔细解释一下,谢了
baihacker 2009-10-17
  • 打赏
  • 举报
回复
//买一送二
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int fac[10];
template<typename T>
int next_perm(T* from, T* to, int n, int id)
{
char buff[20];
int base = fac[n-1];
strcpy(buff, from);
for (int test = n - 1; test > 0; --test)
{
int p = id / base, q = id % base;
to[test] = buff[p];
if (test-p) memmove(buff+p, buff+p+1, sizeof(T)*(test-p));
id = q;
base /= test;
}
to[0] = buff[0];
return 0;
}
int main()
{
fac[0] = 1;
for (int i = 1; i < 10; ++i) fac[i] = i * fac[i-1];
char str[] = "12345";
char dest[20] = {0};
for (int i = 0; i < 120; ++i)
{
next_perm(str, dest, 5, i);
cout << dest << endl;
}
return 0;
}
baihacker 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lihan6415151528 的回复:]
引用 5 楼 baihacker 的回复:
C/C++ code//买一送一#include <iostream>
#include <algorithm>usingnamespace std;

template <typename T>int next_perm(T* data,int n)
{for (int i= n-2; i>=0;--i)for (int j= n-1; j> i;--j)if (data[i] < data[j])
¡­


谢谢,买一送一哈。。

关键还是搞不懂,为什么执行了if之后又去else里面。。
[/Quote]
回到上一层了.
lihan6415151528 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 baihacker 的回复:]
C/C++ code//买一送一#include<iostream>
#include<algorithm>usingnamespace std;

template<typename T>int next_perm(T* data,int n)
{for (int i= n-2; i>=0;--i)for (int j= n-1; j> i;--j)if (data[i]< data[j])
¡­
[/Quote]

谢谢,买一送一哈。。

关键还是搞不懂,为什么执行了if之后又去else里面。。
baihacker 2009-10-17
  • 打赏
  • 举报
回复

//买一送一
#include <iostream>
#include <algorithm>
using namespace std;

template<typename T>
int next_perm(T* data, int n)
{
for (int i = n - 2; i >= 0; --i)
for (int j = n - 1; j > i; --j)
if (data[i] < data[j])
{
swap(data[i], data[j]);
sort(data+i+1, data+n);
return 1;
}
return 0;
}
int main()
{
char str[] = "12345";
int x = 0;
do
{
cout << str << endl;
++x;
} while (next_perm(str, 5));
cout << x << endl;
return 0;
}
baihacker 2009-10-17
  • 打赏
  • 举报
回复
回到上一层了...雷...
lihan6415151528 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 baihacker 的回复:]
只是达到叶子结点的次数一样,输出不一样的
下面有很多重复的
1 2 3 4 5
1 2 3 5 4
1 2 5 3 4
1 2 5 4 3
1 2 3 4 5
1 2 3 5 4
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
1 4 2 3 5
1 4 2 5 3
1 4 5 2 3
1 4 5 3 2
1 4 2 3 5
1 4 2 5 3
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
3 1 2 4 5
3 1 2 5 4
3 1 5 2 4
3 1 5 4 2
3 1 2 4 5
3 1 2 5 4
3 2 1 5 4
3 2 1 4 5
3 2 4 1 5
3 2 4 5 1
3 2 1 5 4
3 2 1 4 5
3 4 1 2 5
3 4 1 5 2
3 4 5 1 2
3 4 5 2 1
3 4 1 2 5
3 4 1 5 2
3 2 1 5 4
3 2 1 4 5
3 2 4 1 5
3 2 4 5 1
3 2 1 5 4
3 2 1 4 5
1 2 3 4 5
1 2 3 5 4
1 2 5 3 4
1 2 5 4 3
1 2 3 4 5
1 2 3 5 4
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
1 4 2 3 5
1 4 2 5 3
1 4 5 2 3
1 4 5 3 2
1 4 2 3 5
1 4 2 5 3
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
4 3 2 1 5
4 3 2 5 1
4 3 5 2 1
4 3 5 1 2
4 3 2 1 5
4 3 2 5 1
4 2 3 5 1
4 2 3 1 5
4 2 1 3 5
4 2 1 5 3
4 2 3 5 1
4 2 3 1 5
4 1 3 2 5
4 1 3 5 2
4 1 5 3 2
4 1 5 2 3
4 1 3 2 5
4 1 3 5 2
4 2 3 5 1
4 2 3 1 5
4 2 1 3 5
4 2 1 5 3
4 2 3 5 1
4 2 3 1 5
5 2 3 1 4
5 2 3 4 1
5 2 4 3 1
5 2 4 1 3
5 2 3 1 4
5 2 3 4 1
5 3 2 4 1
5 3 2 1 4
5 3 1 2 4
5 3 1 4 2
5 3 2 4 1
5 3 2 1 4
5 1 2 3 4
5 1 2 4 3
5 1 4 2 3
5 1 4 3 2
5 1 2 3 4
5 1 2 4 3
5 3 2 4 1
5 3 2 1 4
5 3 1 2 4
5 3 1 4 2
5 3 2 4 1
5 3 2 1 4
total:120
326
[/Quote]
膜拜一下老大,能帮忙解释一下为什么断点第五次时候出现那种情况吗
baihacker 2009-10-17
  • 打赏
  • 举报
回复
void perm(int list[], int k, int m)
的意思在于对list的第k到第m个数进行排列.
当k=m的时候显然就不用了.
否则的话,把第i(k<=i<=m)个数取出来,作为这个排列的头.
后面的再进行排列.
你的第一个swap就是把第i个取出来.
当然,取了之后,还要恢复状态啊,第二个就是恢复.
baihacker 2009-10-17
  • 打赏
  • 举报
回复
只是达到叶子结点的次数一样,输出不一样的
下面有很多重复的
1 2 3 4 5
1 2 3 5 4
1 2 5 3 4
1 2 5 4 3
1 2 3 4 5
1 2 3 5 4
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
1 4 2 3 5
1 4 2 5 3
1 4 5 2 3
1 4 5 3 2
1 4 2 3 5
1 4 2 5 3
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
3 1 2 4 5
3 1 2 5 4
3 1 5 2 4
3 1 5 4 2
3 1 2 4 5
3 1 2 5 4
3 2 1 5 4
3 2 1 4 5
3 2 4 1 5
3 2 4 5 1
3 2 1 5 4
3 2 1 4 5
3 4 1 2 5
3 4 1 5 2
3 4 5 1 2
3 4 5 2 1
3 4 1 2 5
3 4 1 5 2
3 2 1 5 4
3 2 1 4 5
3 2 4 1 5
3 2 4 5 1
3 2 1 5 4
3 2 1 4 5
1 2 3 4 5
1 2 3 5 4
1 2 5 3 4
1 2 5 4 3
1 2 3 4 5
1 2 3 5 4
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
1 4 2 3 5
1 4 2 5 3
1 4 5 2 3
1 4 5 3 2
1 4 2 3 5
1 4 2 5 3
1 3 2 5 4
1 3 2 4 5
1 3 4 2 5
1 3 4 5 2
1 3 2 5 4
1 3 2 4 5
4 3 2 1 5
4 3 2 5 1
4 3 5 2 1
4 3 5 1 2
4 3 2 1 5
4 3 2 5 1
4 2 3 5 1
4 2 3 1 5
4 2 1 3 5
4 2 1 5 3
4 2 3 5 1
4 2 3 1 5
4 1 3 2 5
4 1 3 5 2
4 1 5 3 2
4 1 5 2 3
4 1 3 2 5
4 1 3 5 2
4 2 3 5 1
4 2 3 1 5
4 2 1 3 5
4 2 1 5 3
4 2 3 5 1
4 2 3 1 5
5 2 3 1 4
5 2 3 4 1
5 2 4 3 1
5 2 4 1 3
5 2 3 1 4
5 2 3 4 1
5 3 2 4 1
5 3 2 1 4
5 3 1 2 4
5 3 1 4 2
5 3 2 4 1
5 3 2 1 4
5 1 2 3 4
5 1 2 4 3
5 1 4 2 3
5 1 4 3 2
5 1 2 3 4
5 1 2 4 3
5 3 2 4 1
5 3 2 1 4
5 3 1 2 4
5 3 1 4 2
5 3 2 4 1
5 3 2 1 4
total:120
326
llq520 2009-10-17
  • 打赏
  • 举报
回复
求助下楼主,你的输出语句怎么C++的和C的混合用呢,这样不会出错吗??

64,641

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧