感觉书上对递归操作的栈理解的挺好的,有需要的可以去找一下书看一下
//hanoi problem
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int times = 1;
void
move(char from,int n,char to)
{
printf("%d times: Move disk %d from %c -> %c \n",times++,n,from,to);
}
int
hanoi(int n,char x,char y,char z)
{
if(n == 1)
{
move(x,1,z);
}
else
{
hanoi(n-1,x,z,y);
move(x,n,z);
hanoi(n-1,y,x,z);
}
return times;
}
int main(int argc, char const *argv[])
{
int times ;
int n ;
char x = 'X',y = 'Y',z = 'Z';
printf("please enter the hanoi blocks: ");
while(scanf("%d",&n) == 1)
{
times = hanoi(n,x,y,z);
printf("all move %d times\n",times-1);
}
return 0;
}
非递归算法,即自己构建这么一个进栈入栈的过程,不过
用Visual Studio调试的结果,在移动同样多的盘子情况下,两种方法消耗的内存相差不大,但时间有较大差别,使用迭代的方法花费的时间是递归方法的近十倍。原因有以下几点:
迭代过程中要反复地动态创建变量,这也是时间开销差距的主要原因
递归过程由于编译过程对递归变量和递归函数有很好的优化处理,因而效率较高
迭代代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct record //用于记录递归环境,放入栈中
{
int n;
char moveFrom;
char moveTo;
char swap;
struct record *next;
} record;
typedef struct stack //定义一个栈
{
record * records;
int num;
} stack;
void push(record *record, stack *stack) //向栈内放置元素
{
stack->num++;
record->next = stack->records;
stack->records = record;
}
record * pop(stack *stack) //从栈顶弹出元素
{
record *record;
stack->num--;
record = stack->records;
stack->records = stack->records->next;
return record;
}
//move方法,实现将n个盘子从moveFrom柱借助swap柱移动到moveTo柱
void move(int n, char moveFrom, char moveTo, char swap)
{
stack stack = { NULL, 0 };
record *record1, *p_record;
//初始化栈
record1 = (record *)malloc(sizeof(record));
record1->n = n, record1->moveFrom = moveFrom, record1->moveTo = moveTo;
record1->swap = swap;
push(record1, &stack);
//迭代开始
while (stack.num != 0)
{
//从栈中取出元素,并进行相应操作
p_record = pop(&stack);
if (p_record->n == 1)
{
printf("%c->%c\t", p_record->moveFrom, p_record->moveTo);
free(p_record);
continue;
}
//记录递归环境,并放入栈中
record *record2 = (record *)malloc(sizeof(record));
record *record3 = (record *)malloc(sizeof(record));
record *record4 = (record *)malloc(sizeof(record));
record2->n = p_record->n - 1, record2->moveFrom = p_record->moveFrom,
record2->moveTo = p_record->swap, record2->swap = p_record->moveTo;
record3->n = 1, record3->moveFrom = p_record->moveFrom,
record3->moveTo = p_record->moveTo, record3->swap = p_record->swap;
record4->n = p_record->n - 1, record4->moveFrom = p_record->swap,
record4->moveTo = p_record->moveTo, record4->swap = p_record->moveFrom;
push(record4, &stack);
push(record3, &stack);
push(record2, &stack);
//不要忘记释放内存
free(p_record);
}
}
int main()
{
int n = 3;
//调用move方法
move(n, 'A', 'B', 'C');
return 0;
}