浙江大学陈越教授数据结构PTA 题目——3-5 汉诺塔的非递归实现(顺序堆栈)

一.问题描述:

        1)汉诺塔:有a、b、c三根杆,要求把a杆上的金盘全部移到c杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上。

        2)(n, a, b, c):将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”)

          3)例:

                               

 二.思路

 问题转换为:(n-1,a,c,b)(1,a,b,c)(n-1,b,a,c)

        最开始,共n个盘在a柱上,先要移走(n-1)个盘。(因为最大的那个盘要在最下面,所以最大的盘直接移到c柱,那么(n-1)个盘只能移到b柱)  (n-1,a,c,b)(1,a,b,c)

        最后,要将b柱上的(n-1)个盘移动到c柱上。

三.具体实现

1.利用堆栈,先解决的问题后放入,压入顺序为:(n-1,b,a,c)(1,a,b,c)(n-1,a,c,b)

         再不断将栈顶的问题分解

2.类型定义????????????

        1)*Data前为struct:Data数组中的一个元素  包含  ElementType整体内所有元素

        2)*Data前为enum????????

四.顺序堆栈的基本操作         (链式堆栈见数据结构书77)

1)顺序堆栈定义与创建:

        注意:Stack S是对这个结构体整体的malloc申请

                   S->Data是对Data数组的申请     

 2)判断空、满:

3.入栈

        注意:S->Data  ++(S->Top )  = X;

4.出栈

 四.代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 111

typedef struct {
    int N;
    char A;
    char B;
    char C;
}ElementType;  //汉诺塔问题结构类型

typedef struct LNode *PtrToLNode;
struct LNode{
    ElementType *Data;
    int Top;
    int MaxSize;
};
typedef PtrToLNode Stack;

Stack CreateStack(int MaxSize);
bool IsFull(Stack S);
bool IsEmpty(Stack S);
ElementType Pop(Stack S);
void Push(Stack S,ElementType X);

void Hanoi(int N)
{
    int flag=1;
    Stack S;
    ElementType P,toPush;
    S = CreateStack(MAXSIZE);
    P.N =N;
    P.A ='a';
    P.B ='b';
    P.C ='c';
    Push(S,P);
    while(!IsEmpty(S)){
        P = Pop(S);
        if((flag==1)&&(P.N==1)){
            printf("%c -> %c",P.A ,P.C );
            flag=0;
        }
        else if((flag==0)&&(P.N==1)){
            printf("\n%c -> %c",P.A ,P.C );
        }
        else
        {
            toPush.N =P.N -1;
            toPush.A =P.B ;
            toPush.B =P.A ;
            toPush.C =P.C ;
            Push(S,toPush);
            toPush.N =1;
            toPush.A =P.A ;
            toPush.B =P.B ;
            toPush.C =P.C ;
            Push(S,toPush);
            toPush.N =P.N -1;
            toPush.A =P.A ;
            toPush.B =P.C ;
            toPush.C =P.B ;
            Push(S,toPush);
        }
    }
}

Stack CreateStack(int MaxSize)
{
    Stack S = (Stack)malloc(sizeof(struct LNode));
    S->Data = (ElementType *)malloc(MaxSize*sizeof(ElementType));
    S->Top =-1;
    S->MaxSize = MaxSize;
    return S;
}

void Push(Stack  S,ElementType X) //X为需要压入的元素 
{
    if(IsFull(S)){
        printf("堆栈满");
    }
    else{
        S->Data[++(S->Top )] = X;
    }
}

bool IsFull(Stack S)
{
    return(S->Top == S->MaxSize-1);
}

bool IsEmpty(Stack S)
{
    return(S->Top ==-1);
}

ElementType Pop(Stack S)
{
    if(IsEmpty(S)){
        printf("堆栈空");
        return ;
    }
    else return(S->Data[(S->Top)--]);
}

int main()
{
    int N;
    scanf("%d",&N);
    Hanoi(N);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴同学·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值