栈 stack
后进先出 Last In First Out LIFO 只在表尾进行操作栈的元素必须 “后进先出”。栈的操作只能在这个线性表的表尾进行。注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。
|
大话数据结构 : 栈的顺序 存储结构
|
#include <stdio.h>
//栈的顺序存储定义结构
#define MAXSIZE 10
typedef int SqElemType;
typedef struct
{
SqElemType data[MAXSIZE];
int top; ///用于栈顶指针
}SqStack;
//栈的顺序存储-进栈操作
int Push(SqStack *S, SqElemType e)
{
if (S->top == MAXSIZE - 1)
{
return 0; //说明栈满了,返回错误
}
//栈顶指针增加
S->top++;
//将新插入元素赋值给栈顶空间,这里是一个数组
S->data[S->top] = e;
return 1;
}
//栈的出栈操作,删除栈中的元素用 e 返回
int Pop(SqStack * S, SqElemType *e)
{
if (S->top == -1) //说明是空栈
return 0; // 说明 ?
//将要删除的栈顶元素赋值给e
*e = S->data[S->top];
//栈顶的指针减一
S->top--;
return 1;
}
两栈共享空间:
#include <stdio.h>
//定义两栈共享数据结构
#define MAXSIZE 10
typedef int SqElemType;
typedef struct
{
SqElemType data[MAXSIZE];
int top1; //栈1栈顶指针
int top2; //栈2 栈顶指针
} SqDoubleStack;
//插入元素e 为新的栈顶元素
//还需要判断是栈1 还是栈2
int Push(SqDoubleStack *S, SqElemType e, int stackNumber)
{
//栈已经满了 ,不能再push元素了
if (S->top1 + 1 == S->top2)
return 0;
//栈1 有元素进栈
if (stackNumber == 1)
S->data[++S->top1] = e;
else if (stackNumber == 2)
S->data[--S->top2] = e;
return 1;
}
//弹出栈
int Pop(SqDoubleStack *S, SqElemType *e, int stackNumber)
{
if (stackNumber == 1)
{
//说明栈1 已经是空栈弹出,溢出
if (S->top1 == -1)
return -1;
//将栈1的栈顶元素出栈
*e = S->data[S->top1--];
}
else if (stackNumber == 2)
{
//说明是空栈溢出了
if (S->top2 == MAXSIZE)
return 0;
*e = S->data[S->top2++];
}
return 1;
}
小甲鱼的栈的顺序存储结构 与 大话数据结构 对比一下,差异很容易看出
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
#define STACK_INIT_SIZE 100 //初始化的大小
#define STACKINCREMENT 10 //stackincrement //每次增长的空间的大小
typedef int ElemType;
//定义一个栈
typedef struct
{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack ;
//创建一个栈
int InitStack(sqStack *S)
{
S->base = (ElemType *)malloc( STACK_INIT_SIZE * sizeof(ElemType) );
if (!S->base)
{
exit(0);
}
S->top = S->base; //最开始,栈顶就是栈低
S->stackSize = STACK_INIT_SIZE;
}
//入栈操作
int Push(sqStack *S, ElemType e)
{
//如果栈满 就追加空间
if (S->top - S->base >= S->stackSize)
{
S->base = (ElemType *)realloc(S->base, //重新分配空间
(S->stackSize + STACKINCREMENT) *sizeof(ElemType));
S->top = S -> base + S->stackSize; //设置栈顶
S->stackSize = S->stackSize + STACKINCREMENT; //栈的大小
}
*(S->top) = e;
S->top++;
}
//出栈操作
//弹出的数据存入e
int Pop(sqStack *S, ElemType *e)
{
if (S->top == S->base)
return 0; //栈已经空了
*e = *--(S->top);
}
//清空一个栈 ,是将一个栈中的元素全部作废,但栈本身的物理空间并不发生变化(不是销毁)
int ClearStack(sqStack *S)
{
S->top = S->base;
return 1;
}
//销毁一个栈
//这是要释放物理空间的。
int DestoryStack(sqStack *S)
{
int len , i ;
len = S->stackSize; //获取元素的长度
//因为一开始就已经全部分配了 空间, 所以全部都要清除
for (i = 0; i < len; ++i)
{
free(S->base); //从低向上进行删除操作
S->base++;
}
S->base = S->top = NULL;
S->stackSize = 0;
}
//计算栈当前的容量
int StackLen(sqStack S)
{
return (S.top - S.base);//画张图理解一下, 因为 指针的加减,是走的元素大小的单位,
//每加1 ,就说明进了一格;
}