从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表操作的子集,它们是操作受限的线性表;
但从数据类型角度来看,它们是和线性表大不相同的两种重要的抽象数据类型。
顺序栈,即栈的顺序存储结构是用一组地址连续的存储单元依次存放自栈顶到栈顶的数据元素
typedef struct
{
int * base; //栈底指针,在栈构造之前和摧毁之后,base的值为NULL
int * top; //栈顶指针,在非空栈始终指向栈顶元素的下一个位置
int stacksize; //当前已分配的存储空间
} SqStack;
base栈底指针:始终指向栈底位置,若base=NULL,则栈不存在
top栈顶指针:非空栈中的栈顶指针始终指向栈顶元素的下一个位置
![](https://i-blog.csdnimg.cn/blog_migrate/c54a0f5740b9613e519581d4e5f5b2a3.png)
注意顺序栈的栈底也是存放数据的。
/*
2016年10月28日20:46:25
静态栈
*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define SRAKINCRMENT 10 //存储空间分配增量
typedef struct
{
int * base; //栈底指针,在栈构造之前和摧毁之后,base的值为NULL
int * top; //栈顶指针,在非空栈始终指向栈顶元素的下一个位置
int stacksize; //当前已分配的存储空间
} SqStack;
//函数声明
void InitStack(SqStack * S);
void Push(SqStack * S, int e);
void StackTraverse(SqStack * S);
bool Pop(SqStack * S, int * e);
int main(void)
{
SqStack S;
int val;
InitStack(&S);
Push(&S,1);
Push(&S,2);
Push(&S,3);
Push(&S,4);
StackTraverse(&S);
printf("\n");
Pop(&S, &val);
Pop(&S, &val);
StackTraverse(&S);
return 0;
}
void InitStack(SqStack * S) //初始化静态栈
{
S->base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));
if(NULL == S->base)
{
printf("内存分配失败,程序终止!\n");
exit(-1);
}
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return;
}
void Push(SqStack * S, int e) //压栈
{
if( (S->top - S->base) >= S->stacksize) //如果栈满
{
S->base = (int *)realloc(S->base, (S->stacksize + SRAKINCRMENT ) * sizeof(int));
if(NULL == S->base)
{
printf("内存分配失败,程序终止!\n");
exit(-1);
}
S->top = S->base + S->stacksize;
S->stacksize += SRAKINCRMENT;
}
*(S->top) = e;
++(S->top);
return;
}
void StackTraverse(SqStack * S) //遍历输出,从栈顶开始遍历
{
int * p = S->top;
while( S->base != p)
{
printf("%d\n",*(p-1));
--p;
}
return;
}
bool Pop(SqStack * S, int * e) //出栈
{
if(S->base == S->top) //如果空
{
return false;
}
*e = *(S->top);
--(S->top);
return true;
}