栈
栈是限定仅在表尾进行插入和删除操作的线性表(先进后出)
允许插入和删除的一端叫做栈顶,另一端为栈底;
栈底是固定的,栈顶随着元素的进栈和出栈一直在移动
不含任何元素的叫做空栈
关于出栈的顺序:最先进栈的元素不一定是在最后出栈,有可能一进栈就出栈,一定是栈顶元素先出栈!!!
如果用数组保存数据,一般栈底的下标记为0;
定义变量top指示栈顶元素在数组中的位置,top无论如何都不能超过栈的最大长度maxsize(依据此条件判断栈是否已满)
为什么在创建栈的时候,top要等于-1? 因为当栈有一个元素时,此元素储存在数组下标为0的位置,所以top定义为-1(依据此条件判断栈是否为空)
数组存储代码:
头文件定义
#include<stdio.h>
#include<stdlib.h>
#define ERROR -1
栈的结构定义
typedef struct SNode *Stack;
struct SNode
{
int *data; //或者是int data[maxsize];
int top;
int maxsize;
};
data可以直接改成固定的数组,但会有空间上的浪费,所以写成*data,在创建空栈的函数中调节大小
创建空栈
Stack CreatStack(int maxsize)
{
Stack s =(Stack) malloc(sizeof(struct SNode));
s->data = (int*) malloc(maxsize * sizeof(int));
s->top = -1;
s->maxsize = maxsize;
return s;
}
进栈操作Push
void Push(Stack s, int x)
{
if(s->top == s->maxsize-1) // 判断栈是否已满
{
printf("栈满\n");
return;
}
s->data[++(s->top)] = x;//一定是先++s->top,先创建新的空间,符号顺序不能反
/*分步骤写
s->top++;
s->data[s->top] = x;
*/
}
出栈操作Pop
int Pop(Stack s)
{
if(s->top == -1)
{
printf("栈空\n");
return ERROR;
}
return s->data[(s->top)--]; //s->top--,注意符号位置,元素出栈,top的位置要进行改变
/*//分步骤写
int e = s->data[s->top];
s->top--;
return e;
*/
}
链式存储代码:
通常对于链栈,可以不使用头结点
对于链栈,不存在栈满的情况,即不用考虑栈满条件
对于链表的空是头指针head = NULL,那么对于链栈的空就是top = NULL
头文件定义
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
栈的结构定义
typedef struct SNode *StackNode;
struct SNode{
int data;
struct SNode *next;
};
typedef struct StackList *Stack;
struct StackList{
StackNode top;
int count; //存储的元素个数,即链表的长度
};
创建空栈
因为不带头结点,可以直接在主函数里创建空栈
Stack s;
s->top = NULL;
s->count = 0;
进栈操作Push
类似于链表中的头插法
void Push(Stack s, int x)
{
StackNode p = (StackNode) malloc(sizeof(struct SNode));
p->data = x;
p->next = s->top;
s->top = p;
s->count ++;
}
出栈操作Pop
int Pop(Stack s)
{
if(s->top == NULL)
{
printf("栈空\n");
return ERROR;
}
s->count --;
StackNode p = s->top;
s->top = s->top->next;
return p->data;
}
两栈共享空间
两栈共享一个数组空间;
栈1的栈底为数组下标0的位置,top1指针从-1开始;
栈2的栈底为数组下标maxsize-1的位置,top2指针从maxsize开始;
top1和top2各在数组的两端,向中间靠拢;
头文件定义
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
栈的结构定义
typedef struct SNode *Stack;
struct SNode
{
int *data; //或者是int data[maxsize];
int top1; // 栈1 栈顶的指针
int top2; // 栈2 栈顶的指针
int maxsize; //最大空间
};
创建空栈
Stack CreatStack(int maxszie)
{
Stack s = (Stack) malloc(sizeof(struct SNode));
s->data = (int*) malloc(maxszie * sizeof(struct SNode));
s->top1 = -1;
s->top2 = maxszie;
s->maxsize = maxszie;
}
进栈操作Push
由stack_num判断是从栈1还是栈2进栈
void Push(Stack s, int x, int stack_num)
{
if(s->top1+1 == s->top2)//栈满条件
{
printf("栈满\n");
return;
}
if(stack_num == 1)
s->data[++(s->top1)] = x;
else s->data[--(s->top2)] = x;
}
出栈操作Pop
由stack_num判断是从栈1还是栈2出栈
int Pop(Stack s, int stack_num)
{
//在弹出操作中需要分别判断栈1和栈2是否为空栈
if(stack_num == 1)
{
if(s->top1 == -1) //栈1空条件
{
printf("栈1空\n");
return ERROR;
}else return s->data[(s->top1)--];
}
if(stack_num == 2)
{
if(s->top2 == s->maxsize) //栈2空条件
{
printf("栈2空\n");
return ERROR;
}else return s->data[(s->top2)++];
}
}