LinkedList.h
/* 栈的链式存储结构--链栈 */
typedef int LElemType;
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct LinkedStackNode
{
LElemType data;
struct LinkedStackNode *next;
}LinkedStackNode,*LinkedStackPtr;
typedef struct LinkedStack
{
LinkedStackPtr top;
int count;
}LinkedStack;
Status InitStack(LinkedStack *S); //初始化操作,建立一个空栈S
Status DestroyStack(LinkedStack *S); //栈栈存在,则销毁它
Status ClearStack(LinkedStack *S); //将栈清空
int StackEmpty(LinkedStack S); //若栈为空,返回true,否则返回false
Status GetTop(LinkedStack S,LElemType *e); //若栈存在且非空,用e返回S的栈顶元素
Status Push(LinkedStack *S,LElemType e); //若栈S存在,将新元素e插入栈S中并成为栈顶元素
Status Pop(LinkedStack *S,LElemType *e); //删除栈S中栈顶元素,并用e返回其值
int StackLength(LinkedStack S); //返回栈S的长度
LinkedList.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "LinkedStack.h"
int main(void)
{
LinkedStack S;
InitStack(&S);
printf("已初始化好,现在压栈1,2,3,4");
Push(&S,1);
Push(&S,2);
Push(&S,3);
Push(&S,4);
printf("\n现在的长度是:%d\n",StackLength(S));
printf("现在依次弹栈:");
LElemType e ;
Pop(&S,&e);
printf("%d,",e);
Pop(&S,&e);
printf("%d,",e);
Pop(&S,&e);
printf("%d,",e);
Pop(&S,&e);
printf("%d,",e);
printf("\n现在的长度是:%d\n",StackLength(S));
return 0;
}
Status InitStack(LinkedStack *S) //初始化操作,建立一个空栈S
{
S->top = NULL;
S->count = 0;
return OK;
}
Status DestroyStack(LinkedStack *S) //栈栈存在,则销毁它
{
ClearStack(S);
return OK;
}
Status ClearStack(LinkedStack *S) //将栈清空
{
LinkedStackPtr p = S->top;
while(p)
{
LElemType e;
Pop(S,&e);
}
return OK;
}
int StackEmpty(LinkedStack S) //若栈为空,返回true,否则返回false
{
return S.count == 0;
}
Status GetTop(LinkedStack S,LElemType *e) //若栈存在且非空,用e返回S的栈顶元素
{
if(StackEmpty(S))
{
return ERROR;
}
*e = S.top->data;
return OK;
}
Status Push(LinkedStack *S,LElemType e) //若栈S存在,将新元素e插入栈S中并成为栈顶元素
{
LinkedStackPtr p = (LinkedStackPtr)malloc(sizeof(LinkedStackNode));
p->data = e;
p->next = S->top;
S->top = p;
S->count ++;
return OK;
}
Status Pop(LinkedStack *S,LElemType *e) //删除栈S中栈顶元素,并用e返回其值
{
if(StackEmpty(*S))
{
return ERROR;//为空
}
LinkedStackPtr p = S->top;
*e = p->data;
S->top = p->next;
free(p);
S->count --;
return OK;
}
int StackLength(LinkedStack S) //返回栈S的长度
{
return S.count;
}
对比一下顺序栈和链栈的时间复杂度都为O(1)。对于空间性能,顺序栈需要事先确定一个固定长度,可能会存在内存浪费问题,但它优势是存取时定位很方便,而链栈则要求每个元素都有指针域,同时增加了一些内存开销,但对于栈的长度无限制。因此:
如果栈的使用过程中元素变化不可预料,那么最好用链栈;反之,如果它的变化在可控范围内,应使用顺序栈。