要求:
有帶頭節點的單鏈表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;
}