線性結構實驗 —— 堆疊、佇列(漢諾塔的非遞迴實現)
阿新 • • 發佈:2020-10-31
線性結構實驗 —— 堆疊、佇列(漢諾塔的非遞迴實現)
一、 實驗目的
- 熟練掌握堆疊、佇列的兩種儲存結構實現方式及操作。
- 練習使用堆疊、佇列結構解決問題的能力。
- 通過演算法分析掌握不同儲存結構的操作特點。
二、 實驗內容和要求
問題描述
漢諾塔的非遞迴實現藉助堆疊以非遞迴(迴圈)方式求解漢諾塔的問題(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; }