您的位置:首页 > 其它

全序列算法递归实现――回溯

2013-11-27 10:14 316 查看
这篇博文先考虑简单的数字的情况,如果输入数字4,即输出所有1-4组成的序列,

为了熟悉回溯算法,因为本人一直都不太熟悉回溯算法。。。所以还是特地记一下blog吧,
先上图1:



注意到红线的走向即为回溯算法的走向。
上一下代码,下面再作分析:
#include <stdio.h>
#define MAX 10
int flags[MAX];
int datas[MAX];
int n;
void print(void);
void huisu(int step);
int main(void){
printf("Input a num < 10 :\n");
scanf("%d",&n);
huisu(0);
return 0;
}
void print(){
int i;
for(i=0; i<n;i++){
printf("%d ",datas[i]);
}
printf("\n");
}
void huisu(int step){
int i;
if(step==n)
print();
else{
for(i=0; i<n;i++){
if(!flags[i]){
flags[i] = 1;
datas[step] = i+1;
huisu(step+1);
flags[i] = 0;
}
}
}
}
flags数组用于判断该数字是否访问过,如果访问过即继续寻找未访问的flags,
当step==N(如题目一开始提到的N=4),即已经到达4个数字,即已经找到一个序列输出,否则回溯
下面的图为代码分析图:




注意到步骤6为第一次回溯,此时前面的datas[0]=1,datas[1]=2并没有发生改变。
for循环上一次只走到i=2这个步骤。当回溯到huisu(3)时,继续执行flags[2]=0并且继续走for循环,i++到达i=3的位置,这时flags[3]=1访问过,datas[2]=4,huisu(3)要求for循环再找未被访问的flags,找到flags[2]=1,此时step为3,datas[3]=4并到huisu(4)输出。

作了简单的修改,使其可以支持任意字符的全序列排序:
#include <stdio.h>
#define MAX 10
int flags[MAX];
char result[MAX];
char first[MAX];
int n;
void print(void);
void huisu(int step);
int main(void){
int i;
printf("Input a num < 10 :\n");
scanf("%d",&n);
getchar();//****获得序列中的换行符
for(i=0;i<n;i++)
scanf("%c",&result[i]);//****
for(i=0;i<n;i++)
first[i]=result[i];//****
huisu(0);
return 0;
}
void print(){
int i;
for(i=0; i<n;i++){
printf("%c ",result[i]);//****
}
printf("\n");
}
void huisu(int step){
int i;
if(step==n)
print();
else{
for(i=0; i<n;i++){
if(!flags[i]){
flags[i] = 1;
result[step] = first[i];//****first存放一开始的字符数组
huisu(step+1);
flags[i] = 0;
}
}
}
}
带有//****字样的为修改部分。由数字的全序列里面对datas[step]=i+1进行启发,进行1-4的排序,如果改为datas[step]=i即为进行0-3的排序,对应任意字符数组中的下表0-3的任意排序。记得需要注意的是result对应的为step(每一步都对应有其result值),需要回溯的为step+1,其余都为改变i
本文出自 “再累也要开心D” 博客,请务必保留此出处http://zhangzhang.blog.51cto.com/6250085/1332213
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: