数据结构(二)栈与队列---递归之汉罗塔

(一)汉罗塔的了解

大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

(二)拆分小块,分治思想

只有3个圆盘时

步骤一:将A柱上面的两个碍事的放到B上

步骤二:将A柱上的唯一一个圆盘移动到目标C柱

步骤三:将B柱上的碍事的一个圆盘放入A柱

步骤四:将B柱上的唯一一个圆盘放入目标C柱

步骤五:将A柱子上的唯一一个圆盘放入目标C柱子中

步骤总结

Hanoi(n,A,B,C)将n个圆盘从A移动到C,经过B

最开始:需要移动的圆盘n都在A柱上
1.将A柱的碍事圆盘n-1个经过C,移动到B      Hanoi(n-1,A,C,B)
2.将A中唯一最大圆盘移动到C          move(n,A,C)3.将B中的所有圆盘使用同样的方法移动到C中   Hanoi(n-1,B,A,C)
一次操作,将所有需要移动的圆盘n-1放到B柱上     同样将
所有我们可以进行下一次递归了

(三)代码实现

int count;

void move(int n, char q, char p)
{
    count++;
    printf("%d times Move %d: Move from %c to %c\n", count, n, q, p);
}

void Hanoi(int n, char a, char b, char c)  //函数定义:将n个圆盘,由柱a经过柱b移动到目标柱c
{
    if (n == 1)
        move(n, a, c);  //若是只有一个圆盘,直接移动到目标柱中
    else
    {
        Hanoi(n - 1, a, c, b);  //将a上面的n-1个圆盘经过c移动到b中
        move(n, a, c);       //将剩下的一个最大圆盘从a移动到c
        Hanoi(n - 1, b, a, c);  //同样的想法将b中的n-1个圆盘移动到c中
    }
}

int main()
{
    int n = 3;
    Hanoi(n, ‘X‘, ‘Y‘, ‘Z‘);

    system("pause");
    return 0;
}
int main()
{
    int n = 3;
    Hanoi(n, ‘X‘, ‘Y‘, ‘Z‘);

    system("pause");
    return 0;
}

int main()
{
    int n = 4;
    Hanoi(n, ‘X‘, ‘Y‘, ‘Z‘);

    system("pause");
    return 0;
}

(四)解析

1.假设移动n个圆盘从A柱到B柱的次数为H(n)
2.先把n-1个盘子从A柱移动到B柱,则需要移动的次数为H(n-1)
3.再把最大的那个圆盘从A柱移动到C柱需要一次
4.再把n-1个圆盘从B柱移动到C柱需要H(n-1)
5.由此可以得出
当n=1时,H(1)=1;
当n>1时,H(n)=2*H(n-1)+1;
6.由5得出H(n)=2^n-1  (n>0)

(五)总结

递归写起来简单,想起来有点烧脑....
汉罗塔移动:
1.柱A中有n个圆盘需要移动到目标柱C中
2.将柱A上的n-1个圆盘移动到目标柱B中
3.将柱A中最后1个圆盘移动到目标柱C中
4.将柱B中的n-1个圆盘移动到目标柱C中
注:目标柱在函数中是会变的,不过我们调用的最终目标柱是C
由上面四个步骤可以知道,移动到目标柱的规律是一样的。所以我们定义一个函数用来将所有需要移动的圆盘移动到目标柱上
void Hanoi(int n, char a, char b, char c)
现在使用函数来说明步骤
1.Hanoi(n, ‘X‘, ‘Y‘, ‘Z‘);    将n个圆盘由a=X柱移动到c=Z柱
2.Hanoi(n - 1, a, c, b);      将柱A上的n-1个圆盘移动到目标柱B中
3.move(n, a, c);              将柱A中最后1个圆盘移动到目标柱C中
4.Hanoi(n - 1, b, a, c)       将柱B中的n-1个圆盘移动到目标柱C中
move(n, a, c); //是不是真正移动了某个圆盘,我们只是去打印出来

原文地址:https://www.cnblogs.com/ssyfj/p/9445383.html

时间: 2024-10-28 14:40:25

数据结构(二)栈与队列---递归之汉罗塔的相关文章

二、数据结构之栈、队列、循环队列

二.数据结构之栈.队列.循环队列 顺序栈 Stack.h 结构类型,函数声明: #ifndef _STACK_H_ #define _STACK_H_ typedef int SElementType; ///顺序栈 #define STACK_INIT_SIZE 20 #define STACK_INCREMENT 10 typedef struct { SElementType * base; SElementType * top; int stackSize;///当前栈的大小 }SqSt

【数据结构】栈和队列

栈和队列 容器数据结构是指一些包含了若干个其他相同或不同的数据结构的数据结构,被包含的这些每一个独立的数据结构都被称为一个元素,在一个容器中的元素往往支持相同的操作,具有类似的性质.之前说到过的线性表其实就是一种容器数据结构,本文中介绍的两种最常用的容器数据结构是栈和队列. 从功能上看,栈和队列大多用于计算过程中保存临时数据,这些数据是在计算过程中发现或产生的.在而后的计算中可能会用到这些数据.如果这些数据是固定的个数以及大小的话,可以构建几个变量来储存它们,但是如果这些数据不确定的话,就需要一

数据结构与算法系列研究二——栈和队列

栈和队列的相关问题分析 一.栈和队列定义 栈和队列是两种重要的数据结构.从结构特性角度看,栈和队列也是线性表,其特殊性在于它们的基本操作是线性表的子集,是操作受限的线性表,可称为限定性的数据结构:从数据类型角度看,其操作规则与线性表大不相同,是完全不同于线性表的抽象数据类型.                    图1 栈的结构                                                 图2 队列的结构   1.1.栈是限定在表的一端进行插入和删除操作的线性

数组拷贝、数组函数、通过数组函数来模拟数据结构的栈和队列、回调的意义、数组函数的排序问题、算法以及寻找素数的筛选法

1.数组的拷贝数组拷贝时指针的指向问题. 数组在拷贝时,指针的位置随之复制[这一点拷贝是完全一样]但是如果拷贝的数组的指针是非法的,那么拷贝出新指针的位置进行初始化<?php$arr1=array('123');end($arr1);next($arr1);//这个指针非法$arr2 = $arr1;//这里进行数组的拷贝var_dump(current($arr2));//得到指向‘123’元素的指针var_dump(current($arr1));//此时这个数组的指针有问题?> 但是拷贝

浅谈数据结构系列 栈和队列

计算机程序离不开算法和数据结构,在数据结构算法应用中,栈和队列应用你比较广泛,因为两者在数据存放和读取方面效率比较高,本章节重点讲解两者的基本概念和实现. 基本概念 栈:是一种先进后出,后进先出的数据结构,本质上是线性表,只是限制仅允许在表的一段进行插入和删除工作.此端为栈顶,这是在栈中应用很关键的概念.所有数据的处理都是在栈顶进行的,进栈时,栈中元素增加,栈顶上移一位,出栈时栈顶下移一位.应用中比如:洗碗,每次洗干净的碗放在上面-进栈,取碗,从顶上取出一个-出栈:装子弹-进栈,开枪-出栈. 队

数据结构之栈和队列及其Java实现

栈和队列是数据结构中非常常见又非常基础的线性表,在某些场合栈和队列使用很多,因此本篇主要介绍栈和队列,并用Java实现基本的栈和队列,同时用两个栈实现队列和用两个队列实现栈. 栈:栈是一种基于"后进先出"策略的线性表.在插入时(入栈),最先插入的元素在栈尾,最后插入的元素在栈顶:在删除时(出栈),最后插入的元素先出栈,最先插入的元素最后出栈.由此可见,对栈的插入和删除操作都是在栈顶位置进行的. 在Java中,提供了一个类Stack<E>来实现栈的这些特性,并提供了一些常用的

数据结构之栈和队列

数据结构学习继续向前推进,之前对线性表进行了学习,现在我们进入栈和队列的学习.同样我们先学习一些基本概念以及堆栈的ADT. 栈和队列是两种中重要的线性结构.从数据结构角度看,栈和队列也是线性表,只不过是受限的线性表.因此可以称为限定性数据结构.但从数据类型来看,他们是和线性表大不相同的两类重要的抽象数据类型. 栈:(stack)是限定仅在表尾进行相应插入和删除操作的线性表.因此,对栈来说,表尾有其特殊含义,称为栈顶,表头称为栈底,不含元素的空表称为空栈.栈一个重要特性就是后进先出.OK,我们来看

数据结构之栈与队列

数据结构的有一个重要结构栈,栈这种数据结构就是满足先进后出的这种规则的数据结构就是栈,引用<大话数据结构>中的一个形象例子就是,子弹的弹夹,最先压入弹夹的子弹最后一个出弹夹,正好往一个栈里添加一个元素叫压栈.入栈,从栈里出来一个元素叫弹栈,出栈.指示器就叫栈帧. 栈图 现在就贴上代码: 栈的几个基本操作: #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node{

[ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 2442+1442)

再次面对像栈和队列这样的相当基础的数据结构的学习,应该从多个方面,多维度去学习. 首先,这两个数据结构都是比较常用的,在标准库中都有对应的结构能够直接使用,所以第一个阶段应该是先学习直接来使用,下一个阶段再去探究具体的实现,以及对基本结构的改造! C++标准库中 这里记录一个经典的关于栈和队列的面试题目: 题目:实现一个栈,带有出栈(pop),入栈(push),取最小元素(getMin)三个方法.要保证这三个方法的时间复杂度都是O(1). 思路:重点是getMin()函数的设计,普通思路是设计一