简介- 栈stack
栈(stack)是限定仅在表尾进行插入或删除操作的线性表。
LIFO: Last In First Out 后进先出 表
“思想”:先进后出,后进先出
栈顶 top: 允许插入和删除操作的那一端,我们称之为栈顶
栈尾(栈底, bottom):
1. 顺序栈
特征:栈中各个元素在物理上(内存)上相邻的。
typedef int ElemType;
#define MAX_LEN 1000
struct SeqStack
{
ElemType Elem[MAX_LEN];
int top; //指示栈顶元素的下标
//top == -1, 表示空栈
};
2. 链式栈
特征:栈中各个元素在物理上(内存)上不必相邻
typedef int ElemType;
struct node
{
ElemType data;
struct node *next;
struct node *prev;
};
struct LinkedStack
{
int length; //栈中元素个数
struct node *bottom; //指向栈底结点,first
struct node *top; //指向栈顶结点,last
};
栈的操作
InitStack
DestroyStack
ClearStack
StackEmpty
StackLength
GetTop
Pop
Push
代码实现
1. 顺序栈
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define MAX_LEN 1000
struct SeqStack
{
ElemType Elem[MAX_LEN];
int top; //指示栈顶元素的下标
//top == -1, 表示空栈
};
//初始化一个顺序栈
struct SeqStack* InitStack()
{
struct SeqStack *s = malloc(sizeof(*s));
s->top = -1; // 表示空栈
return s;
}
//销毁一个顺序栈
void DestroyStack(struct SeqStack *s)
{
if (s)
{
free(s);
}
}
//清空一个顺序栈
void ClearStack(struct SeqStack *s)
{
s->top = -1; //清空了
}
/*
判断栈是否为空,如果为空返回1,
否则返回0
*/
int StackEmpty(struct SeqStack *s)
{
return s->top == -1 ;
}
//返回栈中元素的个数
int StackLength(struct SeqStack *s)
{
return s->top + 1;
}
//返回栈顶元素,但不出栈
ElemType GetTop(struct SeqStack*s)
{
return s->Elem[s->top];
}
//出栈
ElemType Pop(struct SeqStack *s)
{
ElemType e = s->Elem[s->top];
s->top--;
return e;
}
//进栈
void Push(struct SeqStack *s, ElemType x)
{
s->Elem[++s->top] = x;
}
//判断运算符 ch1 的优先级是否比ch2要高
//如果要高则返回1,否则返回0
int compare_prior(char ch1, char ch2)
{
if ((ch1 == '*' || ch1 == '/' || ch1 == '%')
&& (ch2 == '+' || ch2 == '-'))
{
return 1;
}
return 0;
}
int calucate(int a , char ch, int b)
{
switch(ch)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
case '%':
return a % b;
default:
//error
break;
}
}
int is_operator(char ch)
{
if (ch == '+' || ch =='-' || ch == '*' || ch =='/' || ch == '%')
return 1;
return 0;
}
int execulate(char *str)
{
struct SeqStack *op = InitStack(); //操作数的栈
struct SeqStack *ch = InitStack(); //运算符的栈
while (*str)
{
//迎接一个操作数,如果是操作数则入栈
if (*str >= '0' && *str <= '9')
{
//取操作数
int s = 0;
while (*str >= '0' && *str <= '9')
{
s = s * 10 + (*str - '0');
str++;
}
//操作数入栈
Push(op, s);
}
//迎接一个运算符
if (is_operator(*str))
{
while (1)
{
/*运算符栈为空 || 我比栈顶元素优级要高*/
if (StackEmpty(ch) || compare_prior(*str, GetTop(ch)))
{
//入栈
Push(ch, *str);
break;
}
else
{
//取运算符栈顶元素出来运算
int a; //第一个操作数
int b; //第二个操作数
char c;//运算符, + - * / %
b = Pop(op);
a = Pop(op);
c = Pop(ch);
Push(op, calucate(a, c, b) );
}
}
}
//
str++;
}
//如果运算符栈不为空,则取出运算
while (!StackEmpty(ch))
{
//取运算符栈顶元素出来运算
int a; //第一个操作数
int b; //第二个操作数
char c;//运算符, + - * / %
b = Pop(op);
a = Pop(op);
c = Pop(ch);
Push(op, calucate(a, c, b) );
}
return Pop(op);
}
int main()
{
char expr[1000];
gets(expr);
//printf("%s %d\n",expr, strlen(expr));
printf("%s = %d\n", expr, execulate(expr));
}
2. 链式栈
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
struct node
{
ElemType data;
struct node *next;
struct node *prev;
};
struct LinkedStack
{
int length; //栈中元素个数
struct node *bottom; //指向栈底结点,first
struct node *top; //指向栈顶结点,last
};
//初始化一个链式栈
struct LinkedStack* InitStack()
{
struct LinkedStack*s = malloc(sizeof(*s));
s->bottom = s->top = NULL;
s->length = 0;
}
//清空栈
void ClearStack(struct LinkedStack *s)
{
struct node *p = s->top;
struct node *pre;
while(p)
{
pre = p->prev;
pre->next = NULL;
p->prev = NULL;
free(p);
p = pre;
}
s->bottom = s->top = NULL;
s->length = 0;
}
//销毁一个链式栈
void DestroyStack(struct LinkedStack * s)
{
ClearStack(s);
free(s);
}
//判断栈是否为空,如果为空,则返回1,
//否则返回0
int StackEmpty(struct LinkedStack *s)
{
return s->length == 0;
}
//返回链式栈中元素的个数
int StackLength(struct LinkedStack * s)
{
return s->length;
}
//返回栈顶元素,但不出栈
ElemType GetTop(struct LinkedStack *s )
{
ElemType e = s->top->data;
return e;
}
//出栈
ElemType Pop(struct LinkedStack *s )
{
ElemType e = s->top->data;
struct node *p = s->top;
s->top = p->prev;
s->top->next = NULL;
p->prev = NULL;
s->length--;
free(p);
return e;
}
//进栈
void Push(struct LinkedStack*s, ElemType e)
{
struct node *p = malloc(sizeof(*p));
p->data = e;
p->next = p->prev = NULL;
if (s->top == NULL)
{
s->top = s->bottom = p;
}
else
{
s->top->next = p;
p->prev = s->top;
s->top = p;
}
s->length++;
}
int main()
{
struct LinkedStack *stack = InitStack();
Push(stack, 100);
Push(stack, 200);
Push(stack, 300);
Push(stack, 400);
Push(stack, 500);
printf("data1=%d\n", Pop(stack));
printf("data2=%d\n", Pop(stack));
printf("data3=%d\n", Pop(stack));
printf("data4=%d\n", Pop(stack));
printf("data5=%d\n", Pop(stack));
}