链式存储优缺点
链栈(运算受限的单链表),只能在栈的一端(栈顶)进行入栈和出栈,所以是先进后出或是后进先出的链表。
优点:
1.基本不会出现栈满上溢情况
2.灵活性高:链栈的容量可以动态调整,不受固定大小的限制。
3.插入和删除操作效率高:由于链栈是基于链表实现的,插入和删除操作的时间复杂度为O(1),效率较高,都在栈顶直接操作。
缺点:
1.存储空间消耗较大:链栈需要额外的空间来存储指针,使得存储空间的消耗相对于顺序栈来说较大。
2.访问元素的效率较低:由于链栈是基于链表实现的,访问元素的时间复杂度为O(n),效率较低。
3.对内存的要求较高:由于链栈需要动态分配内存空间,对内存的要求较高。
代码实现(C语言)
定义链栈
/*栈子系统*/
#include <stdio.h>
#include <malloc.h>
#define MAXSIZE 100 /*数组最大长度为100*/
typedef int DataType; /*定义DataType为int类型*/
typedef struct StackNode /*链栈存储类型*/
{
DataType data; /*定义结点的数据域*/
struct StackNode *next; /*定义结点的指针域*/
} LinkStack;
初始化链栈
不需要定义头节点,*S既代表链栈又代表头指针
LinkStack *InitStack()
{
LinkStack *S;
S = NULL;
return S;
}
判栈空
int EmptyStack(LinkStack *S)
{
if(S == NULL)
return 1;
else
return 0;
}
入栈
LinkStack *Push(LinkStack *S,DataType x)
{
/*进栈函数*/
LinkStack *p = (LinkStack *)malloc(sizeof(LinkStack));/*生成新结点*/
if(!p)
{
printf("内存分配失败");
return 0;
}
p->data=x; /*将x放入新结点的数据域*/
p->next=S; /*将新结点插入链表表头之前*/
S=p; /*新结点作为栈顶*/
return S; /*返回栈顶S*/
}
出栈
LinkStack *Pop(LinkStack *S,DataType *x)
{
/*出栈函数*/
LinkStack *p;
if(EmptyStack(S)) /*调用判空函数EmptyStack(S),判断栈是否为空*/
{
printf("\t栈空,不能出栈!");
return NULL; /*栈空不能出栈*/
}
else /*栈不为空*/
{
*x=S->data; /*栈顶元素取出赋给x*/
p=S; /*p结点指向原栈顶S*/
S=S->next; /*原栈顶S指向其下一个结点*/
free(p); /*释放原栈顶空间*/
return S; /*返回栈顶S*/
}
}
获取栈顶
int GetTop(LinkStack *S, DataType *x)
{
if(EmptyStack(S))
{
printf("栈空,不能取栈顶!");
return 0;
}
*x = S->data;
return 1;
}
获取栈中元素
void ShowStack(LinkStack *S)
{
LinkStack *p = S;
if(p == NULL)
printf("栈空!");
else
{
printf("从栈顶元素起栈中各元素为:");
while(p != NULL)
{
printf("%d",p->data);
p = p->next;
}
}
}
十、二进制数转换
void D_B(LinkStack *S,DataType x)
{
while(x)
{
S=Push(S,x%2); /*余数入栈*/
x/=2; /*被除数data整除以2,得到新的被除数*/
}
printf("转换后的二进制为:");
while (!EmptyStack(S))
{
S=Pop(S,&x); /*依次从栈中弹出每一个余数并输出*/
printf("%d",x);
}
}
表达式转换并求值
void trans(char *exp,char *postexp)
{
/*将中缀表达式转换成后缀表达式函数*/
struct
{
char data[MAXSIZE];
int top;
} op; /*运算符栈*/
int i=0;
op.top=-1;
while(*exp!='#') /*当表达式没结束时*/
{
switch(*exp) /*判断表达式的每个字符*/
{
case '(': /*当字符为'('时*/
op.top++;op.data[op.top]=*exp; /*栈顶指针增1,运算符入栈*/
exp++; /*中缀表达式指针增1*/
break;
case ')': /*当字符为')'时*/
while(op.data[op.top]!='(') /*只要运算符栈顶元素不是'('时*/
{
postexp[i++]=op.data[op.top]; /*将栈顶运算符写入后缀表达式数组中*/
op.top--; /*栈顶指针减1*/
}
op.top--;exp++; /*栈顶指针减1,表达式指针加1*/
break;