第一节汉诺塔与栈

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一节汉诺塔与栈相关的知识,希望对你有一定的参考价值。

1、汉诺塔

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

技术分享图片

记得高中有道题就是求汉诺塔操作的步骤,当大家还是一筹莫展的时候数学老师给出了递推公式,真真令人拍案叫绝!

写程序,求解汉诺塔主要使用了递归的思想,会在之后的《算法思想》中讲解(如果可以坚持下去的话)。

这里的每一个塔,就是一个

2、栈

栈属于线性表,只允许在一端插入(insert,也叫做入栈)和弹出(pop,也叫做出栈)

线性表可以简单理解为一个数组(或者简单链表),除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。

一个栈结构上包含指向栈顶的一个指针以及存储数据的线性表,主要操作为入栈(push)和出栈(pop)。

技术分享图片

我们可以用一个数组模拟栈的实现。

使用一个指针(在数据里面可以用下标)表示栈顶top,最开始top初始化为0表示栈为空,用一个一维数组存储栈的数据。

//top表示栈顶所在的数组下标,top==0,表示栈为空
int top=0;
//使用一个数组(线性表)保存栈的数据
int a[10];

入栈的过程就是top增长的过程,同时把数据存到数组里面。
top++为自增操作,等价于,top=top+1程序员都是偷懒的!

a[top]=b;top++;这两行代码等价于,a[top++]=b;,程序员都是偷懒的!

//入栈
scanf("%d",&b);
//保存数据到栈,栈顶往上移一位
a[top++]=b;

出栈的操作更加简单了,把top减小一位就好了。

//出栈
top--;

技术分享图片

2、栗子

判断回文是学习C语言都会遇到的问题,回文,顾名思义,就是一个正读和反读都一样的字符串,例如ahha、klmlk都是回文,ahhh、pppkhdf不是回文。

“博大精深”的中华传统文化就有精彩的回文:

信言不美,美言不信。 《道德经八十一》

古代的回文诗也是一绝,有兴趣可以自行百度。

那么对于一串英文字符串,如何使用判断是否是回文呢?请思考一下再接着往下看。

思路:

  • 读入字符串
  • 将字符串的前半段push到栈
  • 从后半段开始,与栈顶元素比较,相等则弹出,不等直接break
  • 最后判断栈是否为空,不为空则不是回文,否则是回文

3、代码

这里是完整代码,使用C语言

/*
输入:ahhha
输出:YES
输入:lpppp
输出:NO
*/

#include <stdio.h>
#include <string.h>
int main()
{
    char a[1024], s[1024];
    int i, length, mid, next, top;

    //读入字符串
    gets_s(a);
    length = strlen(a);
    //注意,数组下标起始是很神奇的存在,多一少一等细节很“恐怖”,需要耐心思考和调试
    mid = length / 2 - 1;

    //栈初始化
    top = 0;
    for (i = 0;i <= mid;i++)
        s[++top] = a[i];

    //判断字符串长度,确定中间点起始位置
    if (length % 2 == 0)
        next = mid + 1;
    else
        next = mid + 2;

    //开始匹配
    for (i = next;i < length;i++)
    {
        if (a[i] != s[top])
            break;
        top--;
    }

    //top==0,栈为空,全部匹配完成
    if (top == 0)
        printf("YES");
    else
        printf("NO");

    getchar();getchar();
    return 0;
}

以上是关于第一节汉诺塔与栈的主要内容,如果未能解决你的问题,请参考以下文章

递归与分治策略-第一节:递归和典型递归问题

第一节数据绑定

河内塔与 K 钉

u-boot代码分析--第一节

u-boot代码分析--第一节

单链表与栈