爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      算法基础之回溯

      首页 知识中心 大数据 文章详情页

      算法基础之回溯

      2023-07-11 08:55:50 阅读次数:76

      回溯,算法

      算法基础之回溯(C++示例)

      回溯法(BackTracking)也叫试探法,是一种选优搜索法,按选优条件向前搜索,以达到目标。若探索到某一步,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

      回溯算法类似于枚举的过程,当搜索时遇到不满足条件,回退到上一个,尝试别的路径。

      回溯法从问题本身出发,寻找可能实现的所有情况。和穷举法的思想相近,不同在于穷举法是将所有的情况都列举出来以后再一一筛选,而回溯法在列举过程如果发现当前情况根本不可能存在,就停止后续的所有工作,返回上一步进行新的尝试。

      回溯法常与和递归法结合使用,在回溯法中可以看到有递归的身影。

      八皇后问题、迷宫问题是回溯算法的应用场景。

       

      例1、列举集合 {1,2,3} 中所有子集的问题

      这个问题就可以使用回溯算法。从集合的开头元素开始,对每个元素都有两种选择:取还是舍。当确定了一个元素的取舍之后,再进行下一个元素,直到集合最后一个元素。其中的每个操作都可以看作是一次尝试,每次尝试都可以得出一个结果。将得到的结果综合起来,就是集合的所有子集。

      源码如下:

      #include <stdio.h>
      //设置一个数组,数组的下标表示集合中的元素,所以数组只用下标为1,2,3的空间
      int set[5];
      //i代表数组下标,n表示集合中最大的元素值
      void PowerSet(int i,int n){
          //当i>n时,说明集合中所有的元素都做了选择,开始判断
          if (i>n) {
              for (int j=1; j<=n; j++) {
                  //如果树组中存放的是 1,说明在当初尝试时,选择取该元素,即对应的数组下标,所以,可以输出
                  if (set[j]==1) {
                      printf("%d ",j);
                  }
              }
              printf("\n");
          }else{
              //如果选择要该元素,对应的数组单元中赋值为1;反之,赋值为0。然后继续向下探索
              set[i]=1;PowerSet(i+1, n);
              set[i]=0;PowerSet(i+1, n);
          }
      }
      int main() {
          int n=3;
          for (int i=0; i<5; i++) {
              set[i]=0;
          }
          PowerSet(1, n);
          return 0;
      }
      
      

      运行结果如下:

      1 2 3
      1 2
      1 3
      1
      2 3
      2
      3

       

      例2、八皇后问题

      该问题由国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。其中一种放法(0代表皇后):

      算法基础之回溯

      算法解决思路:

      1. 从棋盘的第一行开始,从第一个位置开始,依次判断当前位置是否能够放置皇后,判断的依据为:同该行之前的所有行中皇后的所在位置进行比较,如果在同一列,或者在同一条斜线上(斜线有两条,为正方形的两个对角线),都不符合要求,继续检验后序的位置。
      2. 如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探。
      3. 如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。

      源码如下:

      #include<iostream>
      using namespace std;
      
      int count = 0;
      int chess[8][8] = {0};
      
      void Print(){
      	printf("解法%d:\n", count);
      	for(int i = 0; i < 8; i++){
      		for(int j = 0; j < 8; j++){
      			if(chess[i][j] == 1)
      				cout << "0 ";//皇后
      			else cout << "* ";
      		}
      		cout << endl;
      	}
      	cout << endl;
      }
      
      bool notDanger(int row, int col){
      	int i, j;
      	for(i = 0; i < 8; i++){	//检查列 
      		if(chess[i][col] == 1)
      			return false;
      	}	
      	for(i = row, j = col; i >=0 && j >=0; i--, j--){	//左对角线 
      		if(chess[i][j] == 1)
      			return false;
      	}	
      	for(i = row, j = col; i >= 0 && j < 8; i--, j++){	//右对角线 
      		if(chess[i][j] == 1)
      			return false;
      	}	
      	return true;
      }
      
      void EightQueen(int row){
      	if(row > 7){	//8行遍历结束 
      		count++;
      		Print();
      		return;
      	}
      	for(int col = 0; col < 8; col++){	//对第row行的每一列尝试赋值 
      		if(notDanger(row, col)){
      			chess[row][col] = 1;
      			EightQueen(row+1);	//每行只有一个 
      			chess[row][col] = 0; //复原 
      		}
      	}
      }
      
      int main(){
      	EightQueen(0);
      	printf("共%d种解法\n", count);
      	return 0; 
      }
      
      

      运行效果如下:

      算法基础之回溯

       

      例3、迷宫问题

      问题描述

      迷宫问题是回溯法的一种应用。迷宫问题的描述为:假设主体放在一个迷宫地图入口处,迷宫中有许多墙,使得大多数的路径都被挡住而无法行进。主体可以通过遍历所有可能到出口的路径来到达出口。当主体走错路时需要将走错的路径记录下来,避免下次走重复的路径,直到找到出口。主体需遵从如下三个原则:

          一次步进只能走一格;
          遇到路径堵塞后,退后直到找到另一条路径可行;
          走过的路径记录下来,不会再走第二次。

      先创建一个二维数组Map[][]并进行初始化,Map[i][j]=1表示该位置是墙体,Map[i][j]=0 表示该位置是路。假设主体(人、动物或者飞行器)放在一个迷宫地图入口处,按上述原则在寻找出口路径。

      源码如下:

      #include <iostream>
      using namespace std;
      
      # define UP 0 //定义上
      # define DOWN 1 //定义下
      # define LEFT 2 //定义左
      # define RIGHT 3 //定义右
      
      # define MAP_MAX 10 //定义最大地图
      int map[MAP_MAX][MAP_MAX] =
      {
          {1,1,1,2,1,1,1,1,1,1},
          {1,0,0,0,1,0,1,1,1,1},
          {1,0,1,0,1,0,1,1,1,1},
          {1,0,1,0,0,0,0,0,1,1},
          {1,0,1,0,1,1,0,1,1,1},
          {1,0,1,0,0,1,0,1,1,1},
          {1,0,1,1,0,1,0,0,0,1},
          {1,0,1,1,1,1,1,1,0,1},
          {1,0,0,0,0,0,0,0,0,1},// 
          {1,1,1,1,1,1,1,1,0,1}//1是墙 ,0是路 ;出发点标2【注*】 
      };
      
      /*
          打印地图
      */
      void print_map()
      {
          int i,j;
          char emt[]=" #R";
          //定义显示的数组
          putchar(' ');
          for(j=0; j<MAP_MAX; j++)
          {
              printf(" %d", j);
          }
          putchar('\n');
          for(i=0; i<MAP_MAX; i++)
          {
              printf("%d ", i);
              for(j=0; j<MAP_MAX; j++)
              {
                  printf("%c ", emt[map[i][j]]);
              }
              putchar('\n');
          }
      }
      
      /*
          单纯的移动,并且进行值的改变
      */
      void move(int &x, int &y, int d)
      {
          switch(d)
          {
          case UP:
              x--;
              break;
          case DOWN:
              x++;
              break;
          case LEFT:
              y--;
              break;
          case RIGHT:
              y++;
              break;
          }
      }
      /*
          检查下一步是否可行
          x,y点开始
          d方向
      */
      int inspect(int x,int y,int d)
      {
          // printf("%d %d %d\n", x,y,d);
          move(x,y,d);
      
          if(x<0 || y<0|| x>=MAP_MAX || y>=MAP_MAX || map[x][y]!=0)
          {
              return 0;
          }
      
          return 1;
      }
      
      void print_pro(int s[2], int e[2], int n){
          /*打印过程*/
          putchar('\n'); //
          printf("当前:(%d, %d) 终点:(%d, %d) 步数:%d\n", s[0],s[1],e[0],e[1],n);
          print_map();
      }
      
      /*
          走迷宫(递归回溯所有可能都走)
          s是开始坐标
          e是结束坐标
          n当前第几步
      */
      int mazes(int s[2],int e[2],int n)
      {
          if(s[0]==e[0] && s[1]==e[1]){
              print_pro(s,e,n);
          }
      
          int i;
          for(i=0; i<4; i++)//向四个方向同时走
          {
              if(inspect(s[0],s[1],i))//检查i方向是否可以行得通
              {
                  int tx = s[0], ty = s[1];//设置临时变量,防止数据混乱
                  move(tx,ty,i);//向i方向移动一步
                  map[tx][ty] = 2;//标记已走
                  int ta[2] = {tx,ty};//传值变量
                  mazes(ta,e,n+1);
                  map[tx][ty] = 0;//取消标记
              }
          }
      }
      
      int main()
      {
          int n = 0;//初始步数
          int s[2] = {0,3};//s初始位置【注*】 
          int e[2] = {9,8};//e终止位置 
          mazes(s,e,n);//调用走迷宫
          putchar('\n');
          return 0;
      }
      
      

      运行效果如下:

      算法基础之回溯

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/cnds123/article/details/119840755,作者:软件开发技术爱好者,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:【Hadoop】HDFS体系结构分析

      下一篇:算法基础之枚举

      相关文章

      2025-05-19 09:04:14

      《剑指Offer》搜索算法题篇——更易理解的思路~

      《剑指Offer》搜索算法题篇——更易理解的思路~

      2025-05-19 09:04:14
      算法
      2025-05-19 09:04:14

      复杂度的OJ练习

      复杂度的OJ练习

      2025-05-19 09:04:14
      代码 , 复杂度 , 思路 , 数组 , 算法
      2025-05-19 09:04:14

      背包问题——“0-1背包”,“完全背包”(这样讲,还能不会?)

      背包问题——“0-1背包”,“完全背包”(这样讲,还能不会?)

      2025-05-19 09:04:14
      动态规划 , 算法
      2025-05-16 09:15:17

      多源BFS问题(4)_地图分析

      多源BFS问题(4)_地图分析

      2025-05-16 09:15:17
      单元格 , 算法 , 网格 , 距离
      2025-05-16 09:15:17

      递归,搜索,回溯算法(3)之穷举,暴搜,深搜,回溯,剪枝

      递归,搜索,回溯算法(3)之穷举,暴搜,深搜,回溯,剪枝

      2025-05-16 09:15:17
      回溯 , 子集 , 数组 , 算法 , 递归
      2025-05-16 09:15:17

      多源BFS问题(2)_飞地的数量

      多源BFS问题(2)_飞地的数量

      2025-05-16 09:15:17
      bfs , grid , 单元格 , 算法
      2025-05-16 09:15:17

      BFS解决最短路问题(4)_为高尔夫比赛砍树

      BFS解决最短路问题(4)_为高尔夫比赛砍树

      2025-05-16 09:15:17
      BFS , lt , 复杂度 , 算法
      2025-05-16 09:15:10

      BFS解决FloodFill算法(3)_岛屿的最大面积

      BFS解决FloodFill算法(3)_岛屿的最大面积

      2025-05-16 09:15:10
      grid , 复杂度 , 算法
      2025-05-14 10:33:31

      【数据结构】第一章——绪论(2)

      【数据结构】第一章——绪论(2)

      2025-05-14 10:33:31
      函数 , 实现 , 打印 , 理解 , 算法 , 输入 , 输出
      2025-05-14 10:33:31

      【数据结构】详细介绍串的简单模式匹配——朴素模式匹配算法

      【数据结构】详细介绍串的简单模式匹配——朴素模式匹配算法

      2025-05-14 10:33:31
      下标 , 元素 , 匹配 , 子串 , 模式匹配 , 算法
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5233695

      查看更多

      最新文章

      《剑指Offer》搜索算法题篇——更易理解的思路~

      2025-05-19 09:04:14

      背包问题——“0-1背包”,“完全背包”(这样讲,还能不会?)

      2025-05-19 09:04:14

      多源BFS问题(4)_地图分析

      2025-05-16 09:15:17

      递归,搜索,回溯算法(3)之穷举,暴搜,深搜,回溯,剪枝

      2025-05-16 09:15:17

      多源BFS问题(2)_飞地的数量

      2025-05-16 09:15:17

      BFS解决最短路问题(4)_为高尔夫比赛砍树

      2025-05-16 09:15:17

      查看更多

      热门文章

      Lc70_爬楼梯

      2024-06-27 09:20:52

      利用函数求出一个数组最大三个数的乘积

      2023-02-13 08:10:07

      冒泡排序法解析

      2024-07-01 01:30:59

      猜字母问题

      2023-02-24 08:30:41

      1791. 找出星型图的中心节点

      2023-02-13 07:55:59

      经典算法——二分查找

      2023-05-11 06:06:36

      查看更多

      热门标签

      算法 leetcode python 数据 java 数组 节点 大数据 i++ 链表 golang c++ 排序 django 数据类型
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      [leetcode] 217. Contains Duplicate

      一块金条切成两半,是需要花费和长度数值一样的铜板的。

      文心一言 VS 讯飞星火 VS chatgpt (90)-- 算法导论8.3 3题

      [leetcode] 48. Rotate Image

      给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复。

      1084. 约瑟夫问题

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号