版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_31803737/article/details/52190733
最近几天都都忙的没时间看书了。游戏打包完成,让我继续来看栈和队列吧。
栈是限定仅在表尾进行插入和删除操作的线性表。
队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性表
一.栈
1.栈的几个定义
允许插入和删除的一端为栈顶,另一端为栈底。
空栈:不含任何数据元素的栈。
栈又称为后进先出(Last In Fisrt Out)的线性表。
栈的插入操作,称为进栈,或入栈,压栈。
栈的删除操作,称为出栈。
2.顺序栈
数组下标为0的一端作为栈底,定义一个top变量来指示栈顶元素在数组中的位置。
当栈中有一个元素时,top=0。空栈的判断条件为top=-1。
//栈的定义
typedef int ElemType; //栈中存储元素类型,定义为int
#define MAX_SIZE 100 //数组长度
typedef struct {
ElemType data[MAX_SIZE]; //栈内元素数组
int top; //栈顶指针
}SqStack;
void push (SqStack *stack , ElemType e){
if(stack->top == MAX_SIZE -1){
//栈满
}else{
stack->top++;//入栈,栈顶 指针+1
stack->data[stack->top] = e;//赋值
}
}
void pop (SqStack * stack , ElemType *e){
if(stack->top == -1){
//空栈
}else{
*e = stack->data[stack->top];
stack->top--;//出栈,栈顶 指针-1
}
}
3.双栈
在数组的两端,分别放两个栈的栈顶指针top1,top2,向中间靠拢。
栈1为空是top1=-1,栈2为空是top2=MAX_SIZE-1,栈满是top1=top2-1。
双栈只针对两个具有相同数据类型的栈的一个设计上的技巧。
//双栈定义
typedef struct {
ElemType data[MAX_SIZE]; //栈内元素数组
int top1; //栈顶指针
int top2;//第二个栈顶指针
}SqDoubleStack;
void push(SqDoubleStack *stack , ElemType e,int stackNum){
if(stack->top1 == stack->top2 - 1){
//栈满
}else if(stackNum == 1){ //栈的标号
stack->top1++;//入栈,栈顶 指针+1
stack->data[stack->top1] = e;//赋值
}else if(stackNum == 2){
stack->top2--;//入栈,栈顶 指针+1
stack->data[stack->top2] = e;//赋值
}
}
void pop(SqDoubleStack * stack , ElemType *e ,int stackNum){
if(stackNum == 1){ //栈的标号
if(stack->top1 != -1){//栈1非空
*e =stack->data[stack->top1];
stack->top2++;//出栈,栈顶 指针-1
}
}else if(stackNum == 2){
if(stack->top2 != MAX_SIZE){//栈2非空
*e=stack->data[stack->top2];
stack->top2++;//出栈,栈顶 指针-1
}
}
}
4.链栈
基本不会出现栈满的情况,除非内存已经没有可以使用的空间。
栈顶指针top 为 头指针。
空栈则表示为top = null;
//栈结点定义
typedef struct {
ElemType data;//数据域
StackNode *next;//指针域
}StackNode,*LinkStackPtr;
//链栈定义
typedef struct {
LinkStackPtr top;//栈顶指针
int count;//栈内元素数量
}LinkStack;
void push(LinkStack *stack , ElemType e){
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(LinkStackPtr));
s->data = e;
//将top指针前移
s->next = stack->top;
stack->top = s;
stack->count++;
}
void pop(LinkStack *stack , ElemType *e){
if(stack->top != NULL){ //非空栈
LinkStackPtr s;
*e = stack->top->data;
//将top指针后移
s = stack->top;
stack->top = s->next;
free(s);
stack->count--;
}
}
对比顺序栈和链栈,时间复杂度都为O(1),对于空间性,顺序栈需要先确定好长度,会造成内存空间的浪费。链栈则要求每个元素都有指针域,增加一些内存的开销,但对于栈的长度无限制。