这道题的题目可以描述为:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
本文中,对于链表结点的定义及接口定义如下:
typedef int DataType;
typedef struct ListNode{
DataType data;
struct ListNode *next;
} ListNode
//初始化
void ListInit(ListNode **ppfirst)
{
assert(ppfirst != NULL);
*ppfirst = NULL;
}
本文中将采用非递归,递归和用栈实现三种方式实现:
1.普通非递归
思路可以理解为:从头到尾遍历整个链表,找到最后一个结点,做打印,然后接着从头遍历,找到倒数第二个结点再做打印,直到打印完头结点为止。
代码如下:
void PrintReverse(ListNode *first)
{
ListNode *end = NULL;//要打印的后一个结点
while (end != first)
{
//每次从第一个结点往前找
ListNode *cur = first;
//找到要打印的结点
while (cur->next != end)
{
cur = cur->next;
}
//要打印的节点
printf("%d", cur->data);
end = cur;
}
}
2.递归算法
思路可以理解为:要实现反过来输出链表,我们访问到一个结点的时候,先递归输出它后面的结点,再输出自身,最后的输出结果就反过来了。
代码如下:
void PrintReserveRecursion(ListNode *first)
{
if (first->next == NULL)
{
printf("%d", first->data);
}
else
{
PrintReserveRecursion(first->next);
//链表中,除了first外的所有结点都已经逆序打印
printf("%d", first->data);
}
}
3.用栈实现
思路可以理解为:将链表从头到尾依次压入栈中,然后依次从栈中弹出栈首元素做打印,直到栈空,最后打印的结果就是链表的逆序打印结果。
有关栈结构体的定义以及相关接口定义如下:
typedef int DataType;
#define MAXSIZE (100)
typedef struct{
DataType array[MAXSIZE];
int top;//起了个别名,含义还是size
}Stack;
void StackInit(Stack *ps)
{
ps->top = 0;
}
void StackDestory(Stack *ps)
{
ps->top = 0;
}
//栈中入放一个元素
void StackPush(Stack *ps,DataType data)
{
assert(ps->top < MAXSIZE);
ps->array[ps->top++] = data;
}
//栈中弹出一个元素
void StackPop(Stack *ps)
{
assert(ps->top>0);
ps->top--;
}
//弹出栈顶元素
DataType StackTop(const Stack *ps)
{
assert(ps->top > 0);
return ps->array[ps->top - 1];
}
//返回栈的大小
int StackSize(const Stack *ps)
{
return ps->top;
}
//返回栈是否为空
int StackEmpty(const Stack *ps)
{
return ps->top == 0 ? 1 : 0;
}
栈的算法实现代码如下:
void PrintReverseStack(ListNode *first)
{
Stack stack;
StackInit(&stack);
ListNode *phead = first;
while (phead != NULL)
{
StackPush(&stack, phead->data);
phead = phead->next;
}
while (!StackEmpty(&stack))
{
DataType t = 0;
t= StackTop(&stack);
printf("%d",t);
StackPop(&stack);
}
}