顺序存储优缺点
栈是操作受限的线性表,只能在栈的一端(栈顶)进行入栈和出栈,所以是先进后出 或是后进先出的线性表。经典案例有进制转换,括号匹配的检验,表达式求值等
优点:
1.插入删除都是在栈顶,时间复杂度O(1)
2.空间利用率高,采用连续的存储空间存储元素
缺点:
1.栈溢出问题:由于顺序栈的存储空间是有限的,当入栈的元素超过栈的容量时,就会发生栈溢出问题,需要采取相应的措施进行处理。
2.扩容开销:容量创建时时固定的,当栈中元素个数超过最大容量时,要进行扩容操作,需要将原栈中元素复制到新栈中,很麻烦。
代码实现(C语言)
定义顺序栈
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100 //最大容量
typedef int SElemType; //栈中元素类型
typedef struct {
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int StackSize; //栈的大小
} SeqStack; //栈
typedef enum { //程序返回值状态码
OK =1,
OVERFLOW = 0,
TRUE = 1,
FALSE = 0,
} Status;
初始化栈
Status InitStack(SeqStack *S) {
S->base = (SElemType *)malloc(sizeof(SElemType) * MaxSize);//动态分配栈内存大小
if (!S->base) //等价于S->base == NULL
{
printf("内存分配失败!");
return OVERFLOW;
}
S->top = S->base; //栈顶指针指向栈底表示空栈
S->StackSize = MaxSize;
return OK;
}
判栈空
Status StackEmpty(SeqStack *S)
{
if(S->top == S->base) //空栈条件
return TRUE;
else
return FALSE;
}
判栈满
Status StackFull(SeqStack *S)
{
if(S->top - S->base == S->StackSize) //栈满条件,用栈顶指针-栈底指针 看是不是等于栈的大小 相等表示栈满
return TRUE;
else
return FALSE
}
入栈
Status Push(SeqStack *S, SElemType e)
{
if (StackFull(S))
{
printf("栈满,不能入栈!");
return FALSE;
}
*(S->top++) = e; // 等价于 S->top = e ; S->top++;
return OK;
}
出栈
Status Pop(SeqStack *S, SElemType *e)
{
if (StackEmpty(S))
{
printf("栈空,不能出栈!");
return FALSE;
}
*e = *(--(S->top)); // S->top -- ; *e = *(S->top);
return OK;
}
求栈长
int StackLength(SeqStack *S)
{
if(S->base)
return (S->top - S->base); //栈顶 - 栈底 = 栈长
}
取栈顶
SElemType GetTop(SeqStack *S)
{
if(StackEmpty(S))
{
printf("栈空,不能取栈顶!");
return FALSE;
}
return *(S->top -1);
}
清空栈
Status StackClear(SeqStack *S)
{
if(S->base)
S->top = S->base; //清空栈只是将栈中元素清楚,只需要把栈顶指针指向栈底就好
return OK;
}
销毁栈
Status StackDestroy(SeqStack *S)
{
if(S->base)
{
free(S->base); //释放掉内存,此时指针还在
S->StackSize = 0; //将大小指针设为0
S->top = S->base =NULL; //将指针指向空
}
return OK;
}
完整示例(C语言实现)
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef int SElemType;
typedef struct {
SElemType *base;
SElemType *top;
int StackSize;
} SeqStack;
typedef enum {
OK =1,
OVERFLOW = 0,
TRUE = 1,
FALSE = 0,
} Status;
// 初始化栈
Status InitStack(SeqStack *S) {
S->base = (SElemType *)malloc(sizeof(SElemType) * MaxSize);
if (!S->base)
{
printf("内存分配失败!");
return OVERFLOW;
}
S->top = S->base;
S->StackSize = MaxSize;
return OK;
}
// 判栈空
Status StackEmpty(SeqStack *S) {
if (S->top == S->base)
return TRUE;
else
return FALSE;
}
// 判栈满
Status StackFull(SeqStack *S) {
if (S->top - S->base == S->StackSize)
return TRUE;
else
return FALSE;
}
// 入栈
Status Push(SeqStack *S, SElemType e) {
if (StackFull(S)) {
printf("栈满,不能入栈!");
return FALSE;
}
*(S->top++) = e; // 等价于 S->top = e ; S->top++;
return OK;
}
// 出栈
Status Pop(SeqStack *S, SElemType *e) {
if (StackEmpty(S)) {
printf("栈空,不能出栈!");
return FALSE;
}
*e = *(--(S->top)); // S->top -- ; *e = *(S->top);
return OK;
}
// 求栈长
int StackLength(SeqStack *S)
{
if(S->base)
return (S->top - S->base); //栈顶 - 栈底 = 栈长
}
// 取栈顶
SElemType GetTop(SeqStack *S) {
if (StackEmpty(S)) {
printf("栈空,不能取栈顶!");
return FALSE;
}
return *(S->top - 1);
}
// 清空栈
Status StackClear(SeqStack *S) {
if (S->base)
S->top = S->base;
return OK;
}
// 销毁栈
Status StackDestroy(SeqStack *S) {
if (S->base) {
free(S->base);
S->StackSize = 0;
S->top = S->base = NULL;
}
return OK;
}
void Menu() {
/*显示菜单子函数*/
printf("\n 顺序栈的各种操作");
printf("\n==================================================");
printf("\n| 1——初始化栈 |");
printf("\n| 2——判栈空 |");
printf("\n| 3——判栈满 |");
printf("\n| 4——入栈操作 |");
printf("\n| 5——出栈操作 |");
printf("\n| 6——求栈长 |");
printf("\n| 7——取栈顶 |");
printf("\n| 8——清空栈 |");
printf("\n| 9——销毁栈 |");
printf("\n| 0——返回 |");
printf("\n==================================================");
printf("\n请输入菜单号(0-9):");
}
int main() {
SeqStack S;
int choice,n,flag,i;
SElemType e,x;
do {
Menu();
scanf("%d", &choice);
switch (choice) {
case 1:
if (InitStack(&S) == OK)
printf("栈初始化成功!\n");
break;
case 2:
if (StackEmpty(&S) == TRUE)
printf("栈为空!\n");
else
printf("栈非空!\n");
break;
case 3:
if (StackFull(&S) == TRUE)
printf("栈已满!\n");
else
printf("栈未满!\n");
break;
case 4:
printf("请输入要入栈的元素个数:");
scanf("%d",&n);
printf("请输入%d个入栈的整数:",n);
for(i=0;i<n;i++)
{
scanf("%d",&x);
flag=Push(&S,x);
}
if(flag==TRUE)
printf("入栈成功!");
break;
case 5:
if (Pop(&S, &e) == OK)
printf("出栈元素为:%d\n", e);
break;
case 6:
printf("栈的长度为:%d\n", StackLength(&S));
break;
case 7:
printf("栈顶元素为:%d\n", GetTop(&S));
break;
case 8:
StackClear(&S);
printf("栈已清空!\n");
break;
case 9:
StackDestroy(&S);
printf("栈已销毁!\n");
break;
case 0:
printf("退出程序\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (choice != 0);
return 0;
}
结语
敬请各位大佬批评指正 日后也会持续更新数据结构相关内容,互相学习😊😊

被折叠的 条评论
为什么被折叠?



