汉诺塔(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语言(顺序栈实现)的主要内容,如果未能解决你的问题,请参考以下文章

汉诺塔 (Tower of Hanoi)java实现

汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法

列表形式的汉诺塔(Tower of Hanoi)Python语言实现

用递归方法解决汉诺塔问题(Recursion Hanoi Tower Python)

Hanoi Tower 汉诺塔的简单分析/C

Acdream 1219 The Towers of Hanoi Revisited(递归汉诺塔问题)