回溯法 是 一种 在 穷举 中,裁剪 不满足 条件 的 分支,已达到 提高 效率的 方法。其基本原型 是 树的 先序遍历,从 树根 到 树叶的路径 是 问题的 一个 解。
回溯法的基本框架 = 确定 解空间 + 深度优先遍历 + 裁剪函数 + 确定结果函数
其中 解空间,分为 子集树 和 排序树。
递归算法通用 模板如下:
回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法。
// 针对N叉树的递归回溯方法
void backtrack (int t)
{
if (t > n) {
// 到达叶子结点,将结果输出
output (x);
}
else {
// 遍历结点t的所有子结点
for (int i = f(n,t); i <= g(n,t); i ++ ) {
x[t] = h[i];
// 如果不满足剪枝条件,则继续遍历
if (constraint (t) && bound (t))
backtrack (t + 1);
}
}
}
下面的 三个例子 都是 根据 这个 模板 来 写的。// Backtrack.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <cstring> #define SET_MAX_SIZE 1000 static bool set[SET_MAX_SIZE]; //获得幂集 //times 表示 当前递归层的层数,从0 层开始 //n 表示 集合的数量 void getPowset(int times,int n){ if (times >= n) { for (int i = 0; i < n; i++) { if (set[i] == true) { printf("%d\t",i+1); } } printf("\n"); } else { for (int i = 0; i < 2; i++) { set[times] = i;getPowset(times+1,n); } } } //打印string的所有子串 //times表示当前 递归层数 void getAllSubChar(int times,char * string){ int len = strlen(string); if (times >= len) { for (int i = 0; i < len; i++) { if (set[i] == true) { printf("%c\t",string[i]); } } printf("\n"); } else{ for (int i = 0; i < 2; i++) { set[times] = i;getAllSubChar(times+1,string); } } } //打印集合中所有等于 N 的组合. void getAllEqual(int times,int arrayLen,int * array,int equal){ int len = arrayLen; if (times >= len) { int sum = 0; for (int i = 0; i < len; i++) { if (set[i] == true) { sum += array[i]; } } if (sum == equal) { for (int i = 0; i < len; i++) { if (set[i] == true) { printf("%d\t",array[i]); } } printf("\n"); } } else { for (int i = 0; i < 2; i++) { set[times] = i; int sum = 0; //裁剪..剪掉 不符合的条件. for (int i = 0; i <= times; i++) { if (set[i]== true) { sum += array[i]; } } if (sum <= equal) { getAllEqual(times+1,arrayLen,array,equal); } } } } int _tmain(int argc, _TCHAR* argv[]) { printf("1~ N 的幂集,请输入N值:"); int n; scanf("%d",&n); printf("1~%d的幂集为:\n",n); getPowset(0,n); char string[SET_MAX_SIZE]; printf("请输入字符串的:"); scanf("%s",string); printf("%s的所有子字符串如下:\n",string); getAllSubChar(0,string); printf("查找集合(3,2,5,6,7,8,10,20,4,15)中 等于 10的 组合\n"); int array[] = {3,2,5,6,7,8,10,20,4,15}; getAllEqual(0,sizeof(array)/sizeof(int),array,10); return 0; }
原文地址:http://blog.csdn.net/fuming0210sc/article/details/44805693