用栈模拟递归的过程,注意入栈顺序和递归顺序相反。
顺序栈:
#include
#include
#include
typedef struct FuncNode *Node;
struct FuncNode {
char a, b, c;
int n;
};
typedef struct StackNode *Stack;
struct StackNode {
Node *Data;
int top;
int maxSize;
};
Node initNode(char a, char b, char c, int n)
{
Node node = (Node)malloc(sizeof(struct FuncNode));
node->a = a, node->b = b, node->c = c, node->n = n;
return node;
}
Stack initStack()
{
Stack stack = (Stack)malloc(sizeof(struct StackNode));
stack->maxSize = 100;
stack->Data = (Node *)malloc(stack->maxSize * sizeof(Node));
stack->top = -1;
return stack;
}
bool isEmpty(Stack stack)
{
return stack->top == -1;
}
bool isFull(Stack stack)
{
return stack->top == stack->maxSize - 1;
}
void Push(Stack s, char a, char b, char c, int n)
{
if (!isFull(s)) {
s->Data[++s->top] = initNode(a, b, c, n);
}
}
Node Pop(Stack s)
{
if (!isEmpty(s)) {
return s->Data[s->top--];
}
}
int main()
{
Stack stack;
Node n;
int N;
scanf("%d", &N);
if (N > 0) {
stack = initStack();
Push(stack, 'a', 'b', 'c', N);
while (!isEmpty(stack)) {
n = Pop(stack);
if (n->n == 1) {
printf("%c -> %c\n", n->a, n->c);
} else if (n->n > 0){
Push(stack, n->b, n->a, n->c, n->n - 1); //入栈顺序和递归时的顺序相反
Push(stack, n->a, n->b, n->c, 1);
Push(stack, n->a, n->c, n->b, n->n - 1);
}
free(n);
}
}
return 0;
}
链栈之前只是粗略看过,这次亲手用了一下,发现很简单,就是运用了链表的头插法。
#include
#include
#include
typedef struct Node *ptrToNode;
struct Node {
char a, b, c;
int n;
ptrToNode next;
};
typedef ptrToNode Stack;
ptrToNode initPtrToNode(char a, char b, char c, int n)
{
ptrToNode node = (ptrToNode)malloc(sizeof(struct Node));
node->a = a, node->b = b, node->c = c, node->n = n, node->next = NULL;
return node;
}
Stack initStack()
{
Stack stack = (Stack)malloc(sizeof(struct Node));
stack->next = NULL;
return stack;
}
bool isEmpty(Stack stack)
{
return stack->next == NULL;
}
void Push(Stack s, char a, char b, char c, int n)
{
ptrToNode node = initPtrToNode(a, b, c, n);
node->next = s->next;
s->next = node;
}
ptrToNode Pop(Stack s)
{
ptrToNode t = NULL;
if (s->next) {
t = s->next;
s->next = t->next;
}
return t;
}
int main()
{
Stack stack;
ptrToNode n;
int N;
scanf("%d", &N);
if (N > 0) {
stack = initStack();
Push(stack, 'a', 'b', 'c', N);
while (!isEmpty(stack)) {
n = Pop(stack);
if (n->n == 1) {
printf("%c -> %c\n", n->a, n->c);
} else if (n->n > 0){
Push(stack, n->b, n->a, n->c, n->n - 1); //入栈顺序和递归时的顺序相反
Push(stack, n->a, n->b, n->c, 1);
Push(stack, n->a, n->c, n->b, n->n - 1);
}
free(n);
}
}
return 0;
}
递归实现汉诺塔:
void hanoiRecursive(char a, char b, char c, int n) //汉诺塔递归实现, a,b,c分别为起始、辅助、终点, n为盘子数
{
if (n > 0) {
hanoiRecursive(a, c, b, n - 1);
printf("%c->%c\n", a, c); //n = 1, 此时a终于有一个可以直接移向c的圆盘
hanoiRecursive(b, a, c, n - 1);
}
}