1. 顺序栈
Stack_Opreator.c
#include
#include
#include
#include
typedef bool status;
#define MAXSIZE 10
struct Stack{
int stack[MAXSIZE];
int top;
};
//创建顺序栈
struct Stack* Stack_Create(){
struct Stack* p = (struct Stack*)malloc(sizeof(struct Stack));
if(p==NULL){
return NULL;
}
memset(p->stack,0,sizeof(p->stack));
p->top = -1;//给初值
return p;
}
status Stack_Push(struct Stack* p ,int data){
//判断是否已经满了
if(p->top==MAXSIZE-1){
printf("栈已满,入栈失败\n");
return false;
}
p->top+=1;
p->stack[p->top] = data;
return true;
}
//出栈
status Stack_Pop(struct Stack* p,int* data){
//判断栈是否为空
if(p->top==-1)
{
printf("栈为空栈,出栈失败!\n");
return false;
}
*data = p->stack[p->top];
p->stack[p->top]=0;//清空
p->top--;
return true;
}
//遍历栈
status Stack_travel(struct Stack* p){
//判断是否为空
int top_1 = p->top;
if(top_1==-1){
printf("栈为空\n");
return false;
}
while(top_1>=0){
printf("%d ",p->stack[top_1]);
top_1--;
}
return true;
}
int main(){
struct Stack* stack_ = Stack_Create();
Stack_Push(stack_,10);
Stack_Push(stack_,20);
Stack_Push(stack_,30);
Stack_travel(stack_);
printf("\n******************\n");
int data;
Stack_Pop(stack_,&data);
printf("取出的栈顶元素:%d\n",data);
Stack_travel(stack_);
return 0;
}
2. 练习
Stack_Express_Get_Value.c
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdbool.h"
#define MAXSIZE_DATA 10
#define MAXSIZE_OPERATOR 10
//顺序栈表达式求值
struct Stack_Data
{
int arr_data[MAXSIZE_DATA];
int top;
};
struct Stack_Operator
{
char arr_operator[MAXSIZE_OPERATOR];
int top;
};
//栈的初始化
struct Stack_Data *Stack_Data_Init()//数字栈的创建
{
struct Stack_Data *stack=(struct Stack_Data*)malloc(sizeof(struct Stack_Data));
if(stack==NULL)
{
return NULL;
}
stack->top=-1;
memset(stack->arr_data,0,sizeof(int)*MAXSIZE_DATA);
return stack;
}
struct Stack_Operator*Stack_Operator_Init()//操作符栈的初始化
{
struct Stack_Operator *stack=(struct Stack_Operator*)malloc(sizeof(struct Stack_Operator));
if(stack==NULL)
{
return NULL;
}
stack->top=-1;
memset(stack->arr_operator,0,MAXSIZE_OPERATOR);
return stack;
}
//栈的遍历
bool Stack_Data_Travel(struct Stack_Data *P)
{
if(P->top==-1)
{
return false;
}
printf("################数字栈的遍历################\n");
while(P->top!=-1)
{
printf("data:%d\n",P->arr_data[P->top]);
P->top--;
}
return true;
}
bool Stack_Operator_Travel(struct Stack_Operator *P)
{
if(P->top==-1)
{
return false;
}
printf("################运算符栈的遍历################\n");
while(P->top!=-1)
{
printf("operator:%c\n",P->arr_operator[P->top]);
P->top--;
}
return true;
}
//栈判空
bool Stack_Data_IsEmpty(struct Stack_Data*P)
{
if(P->top==-1)
{
return true;
}
return false;
}
bool Stack_Operator_IsEmpty(struct Stack_Operator *P)
{
if(P->top==-1)
{
return true;
}
return false;
}
//入栈
bool Stack_Data_Push(struct Stack_Data *P,int data)
{
if(P->top==MAXSIZE_DATA-1)
{
return false;
}
P->top++;
P->arr_data[P->top]=data;
return true;
}
bool Stack_Operator_Push(struct Stack_Operator *P,char operator)
{
if(P->top==MAXSIZE_OPERATOR-1)
{
return false;
}
P->top++;
P->arr_operator[P->top]=operator;
return true;
}
//出栈
bool Stack_Data_Pop(struct Stack_Data *P,int *data)
{
if(P->top==-1)
{
return false;
}
*data=P->arr_data[P->top];
P->top--;
return true;
}
bool Stack_Operator_Pop(struct Stack_Operator *P,char *operator)
{
if(P->top==-1)
{
return false;
}
*operator=P->arr_operator[P->top];
P->top--;
return true;
}
//判断输入的是数字还是运算符, true:运算符, false:数字
char opt[5]={'+','-','*','/','#'};
bool is_opt(char ch)
{
for(int i=0;i=opt2,则opt1出栈,opt2入栈,否则opt2入栈
char Priority(char opt1,char opt2)
{
switch(opt1)
{
case '+':
if(opt2=='+')
{
//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
return '=';//优先级相等
}
else if(opt2=='-')
{
//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
//优先级相等
return '=';
}
else if(opt2=='*')
{
//opt2入栈
return '<';
}
else if(opt2=='/')
{
//opt2入栈
return '<';
}
break;
case '-':
if(opt2=='+')
{
//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
return '=';//优先级相等
}
else if(opt2=='-')
{
//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
//优先级相等
return '=';
}
else if(opt2=='*')
{
//opt2入栈
return '<';
}
else if(opt2=='/')
{
//opt2入栈
return '<';
}
break;
case '*':
if(opt2=='+')
{
return '>';
}
else if(opt2=='-')
{
return '>';
}
else if(opt2=='*')
{
return '=';
}
else if(opt2=='/')
{
return '=';
}
break;
case '/':
if(opt2=='+')
{
return '>';
}
else if(opt2=='-')
{
return '>';
}
else if(opt2=='*')
{
return '=';
}
else if(opt2=='/')
{
return '=';
}
break;
default:return '\0';break;//输入其他不符合法的字符返回为空
}
}
int main()
{
//表达式:5-4x3+5/2
char express[]="5-4*3+5/2#";//可以加一个结束标志"#"
struct Stack_Data *stack_data=Stack_Data_Init();
struct Stack_Operator *stack_operator=Stack_Operator_Init();
int data1;//每一次运算都会从数字栈中取两个数字出来
int data2;
for(int i=0;itop);
printf("运算符栈顶指针:%d\n",stack_operator->top);
while(stack_operator->top!=-1)
{
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
char yun;
Stack_Operator_Pop(stack_operator,&yun);//取出栈顶操作符
printf("出栈的字符:%c\n",stack_operator->arr_operator[stack_operator->top+1]);
switch(yun)
{
case '+':Stack_Data_Push(stack_data,data2+data1);break;
case '-':Stack_Data_Push(stack_data,data2-data1);break;
case '*':Stack_Data_Push(stack_data,data2*data1);break;
case '/':Stack_Data_Push(stack_data,data2/data1);break;
default:break;
}
}
break;
}
if(stack_operator->top==-1)
{
//表示是第一个运算符,进行入栈即可
Stack_Operator_Push(stack_operator,express[i]);
continue;//存入之后直接进入下一次循环,因为入栈了top++,如果不进入下一次循环就会进入else执行
}
else //表示不是第一个运算符
{
//这时候需要判断该栈顶运算符与待入栈的运算符的优先级判断
if(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='='||Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='>')
{
//如果栈顶与运算符优先级与待入栈运算符优先级高或者等于,则出栈栈顶运算符,然后再入栈待入栈运算符
char yun;
Stack_Operator_Pop(stack_operator,&yun);
switch(yun)
{
case '+'://加法运算
//取数字栈中的两个数据进行运算,运算完将结果再入栈
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
//将运算的结果,压入数字栈
Stack_Data_Push(stack_data,data2+data1);
//将待入栈的运算符进行入栈
Stack_Operator_Push(stack_operator,express[i]);
break;
case '-'://减法运算
//取数字栈中的两个数据进行运算,运算完将结果再入栈
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
//将运算的结果,压入数字栈
Stack_Data_Push(stack_data,data2-data1);
//将待入栈的运算符进行入栈
Stack_Operator_Push(stack_operator,express[i]);
break;
case '*'://乘法运算
//取数字栈中的两个数据进行运算,运算完将结果再入栈
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
//将运算的结果,压入数字栈
Stack_Data_Push(stack_data,data2*data1);
//再判断栈顶指针是否比待入栈的优先级高或者等于,如果优先级高或者等于则继续出栈,否则入栈
while(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='='||Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='>')
{
char yun;
Stack_Operator_Pop(stack_operator,&yun);
if(yun=='-')
{
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
//将运算的结果,压入数字栈
Stack_Data_Push(stack_data,data2-data1);
}
if(stack_operator->top==-1)//直到运算符栈为空,才退出判断
{
break;
}
}
//将待入栈的运算符进行入栈
Stack_Operator_Push(stack_operator,express[i]);
break;
case '/'://除法运算
//取数字栈中的两个数据进行运算,运算完将结果再入栈
Stack_Data_Pop(stack_data,&data1);
Stack_Data_Pop(stack_data,&data2);
//将运算的结果,压入数字栈
Stack_Data_Push(stack_data,data2/data1);
//将待入栈的运算符进行入栈
Stack_Operator_Push(stack_operator,express[i]);
break;
defalut:break;
}
}
else if(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='<')
{
//如果待入栈的运算符优先级大于栈顶优先级,则入栈
Stack_Operator_Push(stack_operator,express[i]);
}
}
}
else
{
//如果是数字则入数字栈
Stack_Data_Push(stack_data,express[i]-'0');
}
}
printf("计算结果为:%d\n",stack_data->arr_data[stack_data->top]);
return 0;
}