赞
踩
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
一般回溯的问题有四种:
我其实还没有学到数据结构中的的树结构,但是下面我讲的你没学过也看得懂,只要会循环和递归就能看懂,至于什么广度深度这些偏术语的东西我就不讲了。
这里最基础的应用求所有解中的全排列问题来做分析
(其他的问题基本上就是在这种问题上加上限定条件再做筛选)
算法实现:(c++)
void trackBack( vector<int>nums, vector<int>& flags, vector<int>& track) //这三个参数分别是:你传入的要全排列的数组 要全排列的元素是否被添加到track数组中的标记 一次排列情况 这里我们用一个整型数组来做标记 如果flags[i]=1则表示 nums[i]被添加到track中了 0则表示没有添加到tarck中 { //判断一次排列是否已经完成 if (track.size() == nums.size()) { res.push_back(track);//一次深度遍历等到一条路径添加到结果集中 return ; } for (int i = 0; i <nums.size(); i++) { if (flags[i]) continue; track.push_back(nums[i]);//添加元素到路径中 flags[i] = 1;//标记 trackBack(nums, flags, track);//递归调用回溯函数 track.pop_back();//退格元素 flags[i] = 0;//还原标记 } }
下面用1 2 3的全排列作为示例分析 F一1表示第一层循环的第一次有效循环(有效指的是往track数组中添加了元素的循环)
其中有效循环指添加进了一个元素 循环的层数是指循环所在的函数是递归的层数加1
比如 void func()//第0层递归
{
for(int i=0;i<3;i++)//第0层递归函数中的循环 所以就是第一层循环 有三次
{
func();//这个就是第一层递归 由于循环有三次所以这里有三个第一层递归 第一层递归中的循环就是第二层循环 第二层递归中的循环就是三层循环
那么以此类推被第一层递归调用的就是第二层递归
}
}
好定义好这些了方便描述的关键词之后 进入下面 1 2 3的全排列分析
测试代码(c++):
头文件: #pragma once //回溯算法就是数的遍历 循环实现广度的遍历 递归调用实现深度的遍历 #include<iostream> #include<vector> #include<deque> using namespace std; //template<class T> vector<vector<int>>res; //template<class T> void trackBack( vector<int>nums, vector<int>& flags, vector<int>& track)//这三个参数分别是要遍历的数组 作为标记的bool数组 一次广度遍历的结果 最后返回得到的二维数组 { //判断一次排列是否已经完成 if (track.size() == nums.size()) { res.push_back(track);//一次深度遍历等到一条路径添加到结果集中 return ; } for (int i = 0; i <nums.size(); i++) { if (flags[i]) continue; track.push_back(nums[i]);//添加元素到路径中 flags[i] = 1;//标记 trackBack(nums, flags, track);//递归调用回溯函数 track.pop_back();//退格元素 flags[i] = 0;//还原标记 } } 源文件:*(测试文件) #include"trackBack.h" #include<vector> #include<deque> using namespace std; int main() { vector<int>nums;//输入的元素 vector<int>track;//一次排列的元素集合 vector<int>flags; int n = 0; cout << "请输入您要全排列的元素的个数:"; cin >> n; int elem; cout << "请输入" << n << "个元素:"; for (int i = 0; i < n; i++) { cin >> elem; nums.push_back(elem); flags.push_back(0); } trackBack(nums, flags, track); cout << "全排列为:" << endl; for (int i =0 ; i < res.size(); i++) { for (int j = 0; j < res[i].size(); j++) cout << res[i][j] << " "; cout << endl; } system("pause"); return 0; }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。