汉诺塔(Tower of Hanoi) 递归代码实现 c语言(顺序栈实现)
Posted Dontla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汉诺塔(Tower of Hanoi) 递归代码实现 c语言(顺序栈实现)相关的知识,希望对你有一定的参考价值。
找了个汉诺塔游戏玩,一开始玩给我整懵逼了,后来玩着玩着才慢慢找到诀窍,但到了高阶(> = 7)的时候,老是记不住步骤,果然普通人的脑袋对于递归这种层层递进式线索较长的运算结构,还是不具备优势啊!就好比由一个问题衍生出另一个问题,只有解决了后面的问题才能解决前面的问题,但当问题一个接着一个衍生到七八个问题的时候,最初的问题是啥都给忘得一干二净了!
但是计算机不会,它会把一个一个问题存放在函数调用栈中,就算是后面衍生出几百上千个问题,它也不可能忘记!
下面用我们用代码来实现它,有python和c语言两个版本:
c语言简化版
输入的是当前I
塔的层数n
,
#include <stdio.h>
void hanoi(int n, char I, char J, char K) {
//printf("n = %d\\n", n);
if (n == 1) {
printf("%c -> %c\\n", I, K);
}
else {
hanoi(n-1, I, K, J);
printf("%c -> %c\\n", I, K);
hanoi(n-1, J,I,K);
}
}
int main() {
hanoi(3, 'A', 'B', 'C');
return 0;
}
运行结果:
A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C
C语言强化版(能看到每一步每个塔的情况)(使用了顺序栈库)
main.c
#include <stdio.h>
#include "sequential_stack.h"
struct SqStack A = { 'A' };
struct SqStack B = { 'B' };
struct SqStack C = { 'C' };
void print_hanoi_tower() {
StackTraverse_R(A);
StackTraverse_R(B);
StackTraverse_R(C);
printf("\\n");
}
void hanoi(int n, struct SqStack* I , struct SqStack* J, struct SqStack* K) {
if (n == 1) {
printf("%c -> %c\\n", I->name, K->name);
int e;
Pop(I, &e);
Push(K, e);
print_hanoi_tower();
printf("\\n");
}
else {
hanoi(n-1, I, K, J);
printf("%c -> %c\\n", I->name, K->name);
int e;
Pop(I, &e);
Push(K, e);
print_hanoi_tower();
printf("\\n");
hanoi(n-1, J, I, K);
}
}
int main() {
InitStack(&A);
InitStack(&B);
InitStack(&C);
//汉诺塔阶数
int tower_floor = 4;
for (int i = tower_floor; i > 0; i--)
Push(&A, i);
printf("%d阶汉诺塔:\\n", tower_floor);
print_hanoi_tower();
printf("\\n");
int len = StackLength(A);
hanoi(len, &A, &B, &C);
return 0;
}
sequential_stack.cpp
//顺序栈:泛型版,里面存指针
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#include "sequential_stack.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
int visit(int c)
{
printf("%d ", c);
return OK;
}
/* 构造一个空栈S */
int InitStack(struct SqStack* S)
{
/* S.data=(int *)malloc(MAXSIZE*sizeof(int)); */
S->top = -1;
return OK;
}
/* 把S置为空栈 */
int ClearStack(struct SqStack* S)
{
S->top = -1;
return OK;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
int StackEmpty(struct SqStack S)
{
if (S.top == -1)
return TRUE;
else
return FALSE;
}
/* 返回S的元素个数,即栈的长度 */
int StackLength(struct SqStack S)
{
return S.top + 1;
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
int GetTop(struct SqStack S, int* e)
{
if (S.top == -1)
return ERROR;
else
*e = S.data[S.top];
return OK;
}
/* 插入元素e为新的栈顶元素 */
int Push(struct SqStack* S, int e)
{
if (S->top == MAXSIZE - 1) /* 栈满 */
{
return ERROR;
}
S->top++; /* 栈顶指针增加一 */
S->data[S->top] = e; /* 将新插入元素赋值给栈顶空间 */
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
int Pop(struct SqStack* S, int* e)
{
if (S->top == -1)
return ERROR;
*e = S->data[S->top]; /* 将要删除的栈顶元素赋值给e */
S->top--; /* 栈顶指针减一 */
return OK;
}
/* 从栈底到栈顶依次对栈中每个元素显示 */
int StackTraverse(struct SqStack S)
{
int i;
i = 0;
while (i <= S.top)
{
visit(S.data[i++]);
}
//printf("\\n");
return OK;
}
/* 从栈顶到栈底依次对栈中每个元素显示 */
int StackTraverse_R(struct SqStack S)
{
printf("%c:", S.name);
int i;
i = S.top;
while (i > -1)
{
visit(S.data[i--]);
}
printf("\\t");
return OK;
}
sequential_stack.h
#pragma once
#define MAXSIZE 20
/* 顺序栈结构 */
struct SqStack
{
char name;
int data[MAXSIZE];
int top; /* 用于栈顶指针 */
};
extern int visit(int c);
extern int InitStack(struct SqStack* S);
extern int ClearStack(struct SqStack* S);
extern int StackEmpty(struct SqStack S);
extern int StackLength(struct SqStack S);
extern int GetTop(struct SqStack S, int* e);
extern int Push(struct SqStack* S, int e);
extern int Pop(struct SqStack* S, int* e);
extern int StackTraverse_R(struct SqStack S);
运行结果
4阶汉诺塔:
A:1 2 3 4 B: C:
A -> B
A:2 3 4 B:1 C:
A -> C
A:3 4 B:1 C:2
B -> C
A:3 4 B: C:1 2
A -> B
A:4 B:3 C:1 2
C -> A
A:1 4 B:3 C:2
C -> B
A:1 4 B:2 3 C:
A -> B
A:4 B:1 2 3 C:
A -> C
A: B:1 2 3 C:4
B -> C
A: B:2 3 C:1 4
B -> A
A:2 B:3 C:1 4
C -> A
A:1 2 B:3 C:4
B -> C
A:1 2 B: C:3 4
A -> B
A:2 B:1 C:3 4
A -> C
A: B:1 C:2 3 4
B -> C
A: B: C:1 2 3 4
以上是关于汉诺塔(Tower of Hanoi) 递归代码实现 c语言(顺序栈实现)的主要内容,如果未能解决你的问题,请参考以下文章
汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法
列表形式的汉诺塔(Tower of Hanoi)Python语言实现