目录
一、基本概念
二、以简单全排列认识回溯
(一)决策树
(二)回溯示意图
(三)核心代码
(四)完整代码
三、组合问题
(一)问题
(二)示意图
(三)核心代码
(四)完整代码
(五)剪枝
四、总结
void BackTrack(vector nu, vector& p, vector>& r)
{
if (p.size() == nu.size())//结束条件
{
r.push_back(p);
return;
}
for (int i = 0; i <= nu.size() - 1; i++)
{
if (judge(nu[i], p))//如果为假,本次循环后面的代码不会执行
{
continue;
}
p.push_back(nu[i]);//处理节点
BackTrack(nu, p, r);
p.pop_back();//撤销节点
}
}
#include
#include
#include
using namespace std;
bool judge(int x, vectorp)//判断p中有没有元素x
{
int i = 0;
while (i < p.size())
{
if (x == p[i])
return true;
else
i++;
}
return false;
}
void BackTrack(vector nu, vector& p, vector>& r)
{
if (p.size() == nu.size())//结束条件
{
r.push_back(p);
return;
}
for (int i = 0; i <= nu.size() - 1; i++)
{
if (judge(nu[i], p))//如果为假,本次循环后面的代码不会执行
{
continue;
}
p.push_back(nu[i]);//处理节点
BackTrack(nu, p, r);
p.pop_back();//撤销节点
}
}
void print(vector> r)//遍历
{
for (int i = 0; i < r.size(); i++)
{
for (int j = 0; j < r[i].size(); j++)
{
cout << r[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int n;//元素个数
cout << "输入元素个数:";
cin >> n;
vector>result;//存放符合条件结果的集合
vectorpath;//已走的路径
vectornum(n);//存放元素
cout << "依次输入各元素:";
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
BackTrack(num, path, result);
cout << "全排列结果:" << endl;
print(result);//遍历
}
void BackTrack(int start, int k, vector nu, vector& p, vector>& r)
{
if (p.size()==k)//结束条件
{
r.push_back(p);
return;
}
for (int i = start; i <= nu.size() - 1; i++)
{
p.push_back(nu[i]);//处理节点
BackTrack(i + 1, k, nu, p, r);
p.pop_back();//回溯
}
}
#include
#include
#include
using namespace std;
void BackTrack(int start, int k, vector nu, vector& p, vector>& r)
{
if (p.size()==k)//结束条件
{
r.push_back(p);
return;
}
for (int i = start; i <= nu.size() - 1; i++)
{
p.push_back(nu[i]);//处理节点
BackTrack(i + 1, k, nu, p, r);
p.pop_back();//回溯
}
}
void print(vector> r)//打印
{
for (int i = 0; i < r.size(); i++)
{
for (int j = 0; j < r[i].size(); j++)
{
cout << r[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int n,k;//元素个数和每个组合元素个数
cout << "输入元素个数:";
cin >> n;
vector>result;//存放符合条件结果的集合
vectorpath;//已走的路径
vectornum(n);//存放元素
cout << "依次输入各元素:";
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
cout << "输入组合元素个数:";
cin >> k;
BackTrack(0, k, num, path, result);
cout << "结果:" << endl;
print(result);//打印
}
//输入元素个数:5
//依次输入各元素:1 2 3 4 5
//输入组合元素个数:2
//结果:
//1 2
//1 3
//1 4
//1 5
//2 3
//2 4
//2 5
//3 4
//3 5
//4 5
#include
#include
#include
using namespace std;
void BackTrack(int start, int k, vector nu, vector& p, vector>& r)
{
if (p.size()==k)//结束条件
{
r.push_back(p);
return;
}
for (int i = start; i <= nu.size() - (k-p.size()); i++)
{
p.push_back(nu[i]);//处理节点
BackTrack(i + 1, k, nu, p, r);
p.pop_back();//回溯
}
}
void print(vector> r)//打印
{
for (int i = 0; i < r.size(); i++)
{
for (int j = 0; j < r[i].size(); j++)
{
cout << r[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int n,k;//元素个数和每个组合元素个数
cout << "输入元素个数:";
cin >> n;
vector>result;//存放符合条件结果的集合
vectorpath;//已走的路径
vectornum(n);//存放元素
cout << "依次输入各元素:";
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
cout << "输入组合元素个数:";
cin >> k;
BackTrack(0, k, num, path, result);
cout << "结果:" << endl;
print(result);//打印
}
//输入元素个数:5
//依次输入各元素:1 2 3 4 5
//输入组合元素个数:2
//结果:
//1 2
//1 3
//1 4
//1 5
//2 3
//2 4
//2 5
//3 4
//3 5
//4 5
void backtracking(参数)
{
if (终止条件)
{
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小))
{
处理节点;
backtracking(路径,选择列表);//递归
回溯,撤销处理结果
}
}