数据结构:汉诺塔问题的递归求解和分析

递归方法求解该类问题,是一种简单的思维方法,通常比使用迭代方法更简单。但是,递归方法也有劣势。此处以典型的汉诺塔问题(Tower of Hanoi)为例给予说明。

汉诺塔是根据一个传说形成的数学问题,最早是由法国数学家爱德华·卢卡斯提出。

有三根杆子 A,B,C 。A 杆上有 N 个 ( N > 1 ) (N>1) (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

问:如何移动?最少要移动多少次?

下面链接是一个汉诺塔问题的交互操作程序,读者可以通过操作,尝试解决此问题。https://www.mathsisfun.com/games/towerofhanoi.html

汉诺塔问题,以及之前遇到过的阶乘、斐波那契数列等,都是分治思想的典型应用。

对于汉诺塔问题,解决方法如下,如图 5.1.1 所示。

在这里插入图片描述

图 5.1.1 汉诺塔问题的求解过程

假设 A 柱上最初的盘子总数为 n n n

  • n = 1 n=1 n=1 时,只要将编号为 1 的圆盘从 A 直接移至 C 上即可。
  • 否则,执行如下三步:
    1. 用 C 柱做过渡,将 A 柱上的 ( n − 1 ) (n-1) (n1) 个盘子移到 B 柱上;
    2. 将 A 柱上最后一个盘子直接移到 C 柱上;
    3. 用 A 柱做过渡,将 B 柱上的 ( n − 1 ) (n-1) (n1) 个盘子移到 C 柱上。

由上述求解过程可知,汉诺塔问题符合分治算法的递归求解要求。

【算法步骤】

  1. 如果 n = 1 n=1 n=1 ,则直接将编号为 1 的圆盘从 A 移到 C,递归结束。
  2. 否则:
    • 递归,将 A 上编号为 1 至 n − 1 n-1 n1 的圆盘移到 B,C 做辅助塔;
    • 直接将编号为 n 的圆盘从 A 移到 C;
    • 递归,将 B 上编号为 1 至 n − 1 n-1 n1 的圆盘移到 C,A 做辅助塔。

【算法描述】

//定义搬动操作函数 move(A, n, C) ,将编号为 n 的圆盘
// 从 A 移到 C。
//用全局变量 m 对搬动次数计数
int m = 0;
void move(char A, int n, char C){cout << ++m <<"," << n << "," << A << "," << C << endl;
}void Hanoi(int n, char A, char B, char C){//将 A 上的 n 个圆盘移到 C 上,B 做辅助塔if (n == 1) move(A, 1, C); //将编号为 1 的圆盘从 A 移到 Celse {Hanoi(n-1, A, C, B); //将 A 上不编号为 1 至 n-1 的圆盘移到 B ,C 做辅助塔move(A, n, C);  //编号为 n 的圆盘从 A 移到 CHanoi(n-1, B, A, C); //将 B 上编号为 1 至 n-1 的圆盘移到 C,A 做辅助塔}
}

【算法分析】

假设圆盘数量为 n n n 时,移动圆盘的时间复杂度为 T ( n ) T(n) T(n) ;圆盘数量为 ( n − 1 ) (n-1) (n1) 时时间复杂度 T ( n − 1 ) T(n-1) T(n1) 。根据算法,要将 n − 1 n-1 n1 个圆盘从 A 移到 B(借助 C),然后将这些圆盘从 B 移到 C(借助 A)。再加上将编号为 n 的圆盘从 A 移到 C 所花费的常数时间(用 c c c 表示)则得到递推公式:
T ( n ) = 2 T ( n − 1 ) + c T(n)=2T(n-1)+c T(n)=2T(n1)+c
根据递推公式,有:
T ( n ) = 2 T ( n − 1 ) + c = 2 [ 2 T ( n − 2 ) + c ] + c = 2 2 T ( n − 2 ) + [ 2 + 1 ] c = 2 2 [ 2 T ( n − 3 ) + c ] + [ 2 + 1 ] c = 2 3 T ( n − 3 ) + [ 2 2 + 2 + 1 ] c ⋮ = 2 n − 1 T ( 1 ) + [ 2 n − 2 + ⋯ + 2 0 ] c \begin{split} T(n)&=2T(n-1)+c=2[2T(n-2)+c]+c \\&=2^2T(n-2)+[2+1]c=2^2[2T(n-3)+c]+[2+1]c \\&=2^3T(n-3)+[2^2+2+1]c \\&~\vdots \\&=2^{n-1}T(1)+[2^{n-2}+\cdots+2^0]c \end{split} T(n)=2T(n1)+c=2[2T(n2)+c]+c=22T(n2)+[2+1]c=22[2T(n3)+c]+[2+1]c=23T(n3)+[22+2+1]c =2n1T(1)+[2n2++20]c
显然 T ( 1 ) = c T(1)=c T(1)=c

上述汉诺塔问题算法的时间复杂度是 O ( 2 n ) O(2^n) O(2n) ,即指数阶的时间复杂度。

在第 2 章(因为本文是我编写的《数据结构》考研复习讲义中的节选,所以,读者在阅读的时候,如果遇到类似的表述,勿要深究)已经研究过这种指数阶时间复杂度,在一般情况下, 无法用于解决实际问题,不是一个有效的算法。

对于汉诺塔问题的时间复杂度分析,也可以通过计算移动盘子的次数得到,借用前面给出的交互演示程序和算法,可知:

圆盘数量 n n n移动圆盘次数
1 1 = 2 1 − 1 1=2^1-1 1=211
2 3 = 2 2 − 1 3=2^2-1 3=221
3 7 = 2 3 − 1 7=2^3-1 7=231
⋮ \vdots ⋮ \vdots
n 2 n − 1 2^{n}-1 2n1

因此时间复杂度为 O ( 2 n ) O(2^n) O(2n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.27学习总结 算法题

自己用c语言做的&#xff0c;不尽如意 后面看了题解&#xff0c;用的是c&#xff0c;其中string 变量和字符串拼接感觉比c方便好多&#xff0c;可以用更少的代码实现更好的效果&#xff0c;打算之后去学习c&#xff0c;用c写算法。 递归&#xff0c;不断输入字符&#xff0c;…

vue 图片放大到全局

背景&#xff1a; 在vue项目中&#xff0c;el-image组件图片组件用于展示图片&#xff0c;组件自带的属性preview-teleported&#xff0c;设置为true可以控制图片放大到全局 实现效果&#xff1a; 核心代码&#xff1a; //图片地址&#xff1a;BASEUrl /file/ item.file //这…

【商城实战(75)】数据分析指标体系搭建:从0到1的技术指南

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…

seatunnel配置mysql2hive

SeaTunnel安装教程 # 执行流程 # 下载&#xff0c;解压 # https://mirrors.aliyun.com/apache/seatunnel/2.3.8/?spma2c6h.25603864.0.0.2e2d3f665eBj1E # https://blog.csdn.net/taogumo/article/details/143608532 tar -zxvf apache-seatunnel-2.3.8-bin.tar.gz -C /opt/mo…

SSH项目负载均衡中的Session一致性解决方案‌

SSH项目负载均衡中的Session一致性解决方案‌ 1. 粘性会话&#xff08;Session Sticky&#xff09;‌2. Session复制&#xff08;集群同步&#xff09;‌3. 集中式Session存储‌4. 客户端存储&#xff08;Cookie加密&#xff09;‌方案选型建议‌注意事项‌ 1. 粘性会话&#x…

MySQL 表连接(内连接与外连接)

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 1、表连接的核心概念 1.1 为什么需要表连接&#xff1f; 2、内连接&a…

解锁Spring Boot异步编程:让你的应用“飞“起来!

引言&#xff1a;从点餐说起 &#x1f354; 想象你在快餐店点餐&#xff1a; 同步模式&#xff1a;排队等餐&#xff0c;队伍越来越长&#xff08;就像卡死的服务器&#xff09;异步模式&#xff1a;拿号后去旁边坐着等&#xff08;服务员喊号通知你&#xff09; 今天我们就…

做一个有天有地的css及html画的旋转阴阳鱼

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>天地阴阳</title><style>/* 重置默认样…

ngx_http_core_main_conf_t

定义在 src\http\ngx_http_core_module.h typedef struct {ngx_array_t servers; /* ngx_http_core_srv_conf_t */ngx_http_phase_engine_t phase_engine;ngx_hash_t headers_in_hash;ngx_hash_t variables_hash;…

计算机二级(C语言)考试高频考点总汇(二)—— 控制流、函数、数组和指针

目录 六、控制流 七、函数 八、数组和指针 六、控制流 76. if 语句可以&#xff08;嵌套&#xff09;&#xff0c; if 语句可以嵌套在另一个 if 语句内部&#xff0c;形成&#xff08;嵌套的条件判断结构&#xff09;&#xff0c;用于处理更复杂的条件判断逻辑。 77. els…

WebRTC协议全面教程:原理、应用与优化指南

一、WebRTC协议概述 **WebRTC&#xff08;Web Real-Time Communication&#xff09;**是一种开源的实时通信协议&#xff0c;支持浏览器和移动应用直接进行音频、视频及数据传输&#xff0c;无需插件或第三方软件。其核心特性包括&#xff1a; P2P传输&#xff1a;点对点直连…

使用 WSL + Ubuntu + Go + GoLand(VSCode) 开发环境配置指南

1. 安装和配置 WSL 与 Ubuntu 启用 WSL 功能(以管理员身份运行 PowerShell): wsl --install 或手动启用: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachi…

element-plus中,Tour 漫游式引导组件的使用

目录 一.Tour 漫游式引导组件的简单介绍 1.作用 2.基本使用 3.展示效果 二.实战1&#xff1a;介绍患者病历表单 1.要求 2.实现步骤 3.展示效果 结语 一.Tour 漫游式引导组件的简单介绍 1.作用 快速了解一个功能/产品。 2.基本使用 从官网复制如下代码&#xff1a; &…

39-Ajax工作原理

1. 简明定义开场 “AJAX(Asynchronous JavaScript and XML)是一种允许网页在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页内容的技术。它通过JavaScript的XMLHttpRequest对象或现代的Fetch API实现异步通信。” 2. 核心工作原理 "AJAX的工作…

Python 爬虫案例

以下是一些常见的 Python 爬虫案例&#xff0c;涵盖了不同的应用场景和技术点&#xff1a; 1. 简单网页内容爬取 案例&#xff1a;爬取网页标题和简介 import requests from bs4 import BeautifulSoup url "https://www.runoob.com/" response requests.get(url) …

【C++进阶】函数:深度解析 C++ 函数的 12 大进化特性

目录 一、函数基础 1.1 函数定义与声明 1.2 函数调用 1.3 引用参数 二、函数重载&#xff1a;同名函数的「多态魔法」&#xff08;C 特有&#xff09; 2.1 基础实现 2.2 重载决议流程图 2.3 与 C 语言的本质区别 2.4 实战陷阱 三、默认参数&#xff1a;接口的「弹性设…

Redis的基础,经典,高级问题解答篇

目录 一&#xff0c;基础 二&#xff0c;经典 缓存雪崩&#xff1a; 1. Redis事务的原子性 2. 与MySQL事务的区别 1. 主从复制原理 2. 哨兵模式故障转移流程 3. 客户端感知故障转移 三&#xff0c;高级 一&#xff0c;基础 Redis的5种基础数据类型及使用场景&#xf…

【蓝桥杯】好数

好数 问题描述代码解释代码 好数 问题描述 一个整数如果按从低位到高位的顺序&#xff0c;奇数位 (个位、百位、万位 ⋯ ) 上的数字是奇数&#xff0c;偶数位 (十位、千位、十万位 ⋯ ) 上的数字是偶数&#xff0c;我们就称之为 “好数”。 给定一个正整数 N&#xff0c;请计算…

利用 Patroni + etcd + HAProxy 搭建高可用 PostgreSQL 集群

在生产环境中&#xff0c;数据库的高可用性是系统稳定运行的关键。本文将详细讲解如何利用 Docker 部署一个由 etcd、Patroni 和 HAProxy 组成的 PostgreSQL 高可用集群&#xff0c;实现自动故障转移和负载均衡。 架构概述 本架构主要包括三部分&#xff1a; etcd 集群 etcd …

bash 和 pip 是两种完全不同用途的命令,分别用于[系统终端操作]和[Python 包管理]

bash 和 pip 是两种完全不同用途的命令&#xff0c;分别用于 系统终端操作 和 Python 包管理。以下是它们的核心区别、用法及常见场景对比&#xff1a; 1. 本质区别 特性bashpip类型Shell 命令解释器&#xff08;一种脚本语言&#xff09;Python 包管理工具作用执行系统命令、…