要求:
有带头节点的单链表L,编写算法实现从尾到头反向输出每个结点的值。
分析:
这里有一种思路是利用栈,在正向遍历单链表的时候进行入栈,然后遍历完成之后依次出栈,既可实现反向输出。
既然可以用栈,那么也可以用递归的方式来实现。然而递归是利用的栈,实质上是相同的。
递归的时候,系统需要设立一个“工作栈”作为整个递归函数运行期间使用的数据存储区。每递归一次,则需要入存实在参数,所有局部变量以及上一层的返回地址等信息。这样一来,递归的效率远不如直接用栈实现。
下面给出了利用栈实现该功能的代码。
#include<stdio.h>
#include<stdlib.h>
#define STACK_INNIT_SIZE 20
#define STACKINCRMENT 5
struct SqStack//栈
{
int *base;
int *top;
int stacksize;
};
struct Lnode//链表结点
{
int data;
Lnode *next;
};
int InitStack(struct SqStack *S)//构造空栈
{
S->base = (int *)malloc(STACK_INNIT_SIZE * sizeof(int));
if(!S->base)
return 0;
S->top=S->base;
S->stacksize = STACK_INNIT_SIZE;
return 1;
}
int Push(struct SqStack *S,int e)//入栈
{
if(S->top - S->base>=S->stacksize)
{
S->base = (int *)realloc(S->base,(S->stacksize+STACKINCRMENT) * sizeof(int));
if(!S->base)
return 0;
S->top = S->base+S->stacksize;
S->stacksize += S->stacksize;
}
*(S->top) = e;
S->top++;
return 1;
}
int Pop(struct SqStack *S)//删除栈顶元素,并返回
{
if(S->top==S->base)
{
printf("空栈");
return 0;
}
S->top--;
int e = *(S->top);
return e;
}
int Init(struct Lnode *L, int i)
{
struct Lnode *p;
struct Lnode *q=L;
int j=0;
while(j<i)
{
p = (struct Lnode *)malloc(sizeof(struct Lnode));
scanf("%d",&((*p).data));
(*p).next =NULL;
(*q).next = p;
q= p;
j++;
}
return 0;
}
int r_print(struct Lnode *L)
{
struct Lnode *p = L->next;
struct SqStack S;
InitStack(&S);
while(p!=NULL)
{
Push(&S,(*p).data);
p = (*p).next;
}
int i;
while(S.top!=S.base)
{
i = Pop(&S);
printf("%d\t",i);
}
return 0;
}
int main()
{
struct Lnode Head;
struct Lnode *L=&Head;
(*L).next = NULL;
int i = 5;
Init(L,i);
r_print(L);
return 0;
}