1. 程式人生 > 實用技巧 >線性結構實驗 —— 堆疊、佇列(漢諾塔的非遞迴實現)

線性結構實驗 —— 堆疊、佇列(漢諾塔的非遞迴實現)

線性結構實驗 —— 堆疊、佇列(漢諾塔的非遞迴實現)

一、 實驗目的

  1. 熟練掌握堆疊、佇列的兩種儲存結構實現方式及操作。
  2. 練習使用堆疊、佇列結構解決問題的能力。
  3. 通過演算法分析掌握不同儲存結構的操作特點。

二、 實驗內容和要求

問題描述

漢諾塔的非遞迴實現藉助堆疊以非遞迴(迴圈)方式求解漢諾塔的問題(n, a, b, c),即將N個盤子從起始柱(標記為“a”)通過藉助柱(標記為“b”)移動到目標柱(標記為“c”),並保證每個移動符合漢諾塔問題的要求。

輸入格式

輸入為一個正整數N,即起始柱上的盤數。

輸出格式

每個操作(移動)佔一行,按柱1 -> 柱2的格式輸出。

輸入樣例

3

輸出樣例:

a -> c 
a -> b
c -> b
a -> c 
b -> a 
b -> c 
a -> c

三、原始碼

#include <stdio.h>
#include<stdlib.h>

struct Node  //將棧內元素放入一個結構體中
{
    char start; //起始柱
    char mid; //藉助柱
    char goal;  //目標柱
    int num; //起始柱上的盤數
};


typedef int Position; //棧頂位置
typedef struct Node ElementType; //將堆疊的元素型別具體化
//typedef enum { false, true } bool;

/*堆疊的順序表定義*/
typedef struct SNode* PtrToSNode;
struct SNode
{
    ElementType* data; //儲存元素的陣列
    Position Top; //堆疊的棧頂指標
    int Maxsize; //堆疊的最大容量
};
typedef PtrToSNode Stack;


bool push(Stack S, int n, char a, char b, char c);
struct Node pop(Stack S);

/*
生成空堆疊,其最大長度為 Maxsize
*/
Stack CreateStack() {
    Stack S;
    S = (Stack)malloc(sizeof(struct SNode));
    S->Maxsize = 1000;
    S->data = (struct Node*)malloc(S->Maxsize * sizeof(struct Node));
    S->Top = -1;
    return S;
}

/*
判斷堆疊S是否已滿。
若S中元素個數等於 Maxsize 時返回 TRUE
否則返回 FALSE
*/
bool IsFull(Stack S) {
    return (S->Top == S->Maxsize - 1);
}
/*
將元素X壓入堆疊。
若堆疊已滿,返回 FALSE
否則將資料元素 X 插入到堆疊 S 棧頂,返回 TRUE
*/
bool push(Stack S, int n, char a, char b, char c)
{
    if (IsFull(S)) {
        printf("Full Stack.\n");
        return false;
    }
    else {
    S->Top++;
    S->data[S->Top].start = a;
    S->data[S->Top].mid = b;
    S->data[S->Top].goal = c;
    S->data[S->Top].num = n;
    return true;
    }
}
/*
判斷堆疊 S 是否為空。
若是返回 TRUE
否則返回 FALSE
*/
bool IsEmpty(Stack S) {
    return (S->Top == -1);
}
/*
刪除並返回棧頂元素。
若堆疊為空,返回錯誤資訊
否則將棧頂資料元素從堆疊中刪除並返回
*/
ElementType pop(Stack S)
{
    if (IsEmpty(S)) {
        printf("Empty Stack.\n");
        ElementType e;
        e.num = -1;
        return e;
    }
    else
        return S->data[S->Top--];
}

/*藉助棧的非遞迴實現*/
int main()
{
    int n;
    scanf_s("%d", &n);
    Stack S;
    S = CreateStack();
    struct Node m;
    push(S, n, 'a', 'b', 'c');  //將初始狀態壓棧
    while (S->Top >= 0)  //堆疊不空
    {
        m = pop(S); //彈出棧頂元素
        if (m.num == 1)
        {
            printf("%c -> %c\n", m.start, m.goal);
        }
        else
        {
            /* n-1個盤,從輔助柱,藉助源柱,移動到目標柱 */
            push(S, m.num - 1, m.mid, m.start, m.goal);

            /* 最後一個盤,從源柱,藉助輔助柱,移動到目標柱 */
            push(S, 1, m.start, m.mid, m.goal);

            /* n-1個盤,從源柱,藉助目標柱,移動到輔助柱 */
            push(S, m.num - 1, m.start, m.goal, m.mid);
        }
    }
    return 0;
}