栈(LIFO):运算所限的线性表,限制它的插入和删除操作仅在表的一段进行。
栈顶(Top)插入、删除。另一端为栈底。
n=0称为空栈,插入新元素称为入栈、进栈。
删除称为出栈、退栈。
特点:先进后出。
栈的逻辑结构:线性表。顺序存储顺序栈,链接方式存储链栈。
基本运算:初始化栈、判断空、入栈、出栈、读栈顶元素。
顺序栈存储结构
#define MAX 1024
typedef int DataType;
typedef struct
{
DataType data[MAX];
int top;
} Stack;
Stack *s;
初始化栈
Stack * init()
{
Stack * s;
//申请指定空间的栈
s = (Stack *)malloc(sizeof(Stack));
s->top = -1;
return s;
}
判断空
int empty(Stack *s){
//如果为空返回1,否则返回0
if (s->top == -1) return 1;
else return 0;
}
入栈:判断是否栈满,如果是提示越界,返回0。否则递增栈顶指针(top),向栈顶指针指向的位置填入元素,返回1。
int push(Stack *s,DataType x){
if (s->top == MAX-1){
printf("OverFlow");
return 0;
}
s->top++;
s->data[s->top] = x;
return 1;
}
出栈:如果栈为空,这时出栈没有元素,会出现溢出的情况,打印提示信息。否则递减栈顶指针top.
void push(Stack *s){
//也可以直接调用empty函数判断是否为空
if (s->top==-1){
printf("OverFlow");
}else{
s->top--;
}
}
读栈顶元素:如果不为空,直接返回栈顶指针指向位置的值。否则打印提示信息,并返回0。
DataType top(Stack *s){
if (!empty(s)){
return (s->data[s->top]);
}else{
printf("Stack is Empty!");
return 0;
}
}
链式栈的存储结构
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node * next;
} LinkStack;
LinkStack * top;
初始化栈
LinkStack * init(){
return null;
}
判断空
int empty(LinkStack *top){
if (!top){
return 1;
}else{
return 0;
}
}
入栈
LinkStack * push(LinkStack * top,DataType x){
LinkStack * s;
s = (LinkStack *)malloc(sizeof(LinkStack));
s->data = x;
s->next = top;
top = s;
return top;
{
出栈
LinkStack * pop(LinkStack * top){
LinkStack * p;
p = top;
top = top->next;
free(p);
return top;
}
读栈顶元素
DataType topLinkStack(LinkStack * top){
return top->data;
}
可以看出顺序栈和链栈的插入和删除的时间复杂度都为O(1),区别是链栈是动态申请的空间,顺序栈是在定义栈的时候就申请好了空间的大小。