顺序栈 链式栈
栈是先进后出 可以通过顺序表封装一个顺序栈//代码如下
#pragma once
//定长的顺序栈
//todo 将定长的顺序栈改成泛型
//todo 将定长的顺序栈改成不定长
#define SIZE 10
typedef struct Stack
{
int elem[SIZE];//void *
int top;//栈顶指针,标记当前可以存放数据的下标
}Stack,*PStack;
void InitStack(PStack ps);
//入栈
bool Push(PStack ps,int val);
bool IsEmpty(PStack ps);
//获取栈顶元素的值,但不删除
bool GetTop(PStack ps,int *rtval);
//获取栈顶元素的值,且删除
bool Pop(PStack ps,int *rtval);
void Clear(PStack ps);
void Destroy(PStack ps);
#include <stdio.h>
#include <assert.h>
#include "stack.h"
void InitStack(PStack ps)
{
assert(ps != NULL);
ps->top = 0;
}
static bool IsFull(PStack ps)
{
return ps->top == SIZE;
}
//入栈
bool Push(PStack ps,int val)//O(1)
{
if(IsFull(ps))
{
return false;
}
ps->elem[ps->top++] = val;
return true;
}
bool IsEmpty(PStack ps)
{
return ps->top == 0;
}
//获取栈顶元素的值,但不删除
bool GetTop(PStack ps,int *rtval)//O(1)
{
if(IsEmpty(ps))
{
return false;
}
*rtval = ps->elem[ps->top - 1];
return true;
}
//获取栈顶元素的值,且删除
bool Pop(PStack ps,int *rtval)//O(1)
{
if(IsEmpty(ps))
{
return false;
}
*rtval = ps->elem[--ps->top];
return true;
}
void Clear(PStack ps);
void Destroy(PStack ps);
#include "stack.h"
int main()
{
Stack s;
InitStack(&s);
for(int i=0;i<15;i++)
{
Push(&s,i);
}
int tmp;
while(!IsEmpty(&s))
{
Pop(&s,&tmp);
printf("%d\n",tmp);
}
return 0;
}
建立一个链式栈通过链式栈把方程改成中缀
#pragma once //链式栈,利用带头节点的单链表实现,栈顶在表头 typedef struct SNode { int data; struct SNode *next; //链式栈的栈顶在表头,不需要额外添加栈顶指针 }SNode,*PStack; void InitStack(PStack ps); //入栈 bool Push(PStack ps,int val); bool IsEmpty(PStack ps); //获取栈顶元素的值,但不删除 bool GetTop(PStack ps,int *rtval); //获取栈顶元素的值,且删除 bool Pop(PStack ps,int *rtval); void Clear(PStack ps); void Destroy(PStack ps); #pragma once //存放运算符的优先级 /********************************************************************************************************* 运算符优先级,数值越小优先级越高 *********************************************************************************************************/ #define OPERA_PRIO_PLUS_IN 4 /* 栈内 + */ #define OPERA_PRIO_MINUS_IN 4 /* 栈内 - */ #define OPERA_PRIO_MULTIPLY_IN 2 /* 栈内 * */ #define OPERA_PRIO_DIVISION_IN 2 /* 栈内 / */ #define OPERA_PRIO_LEFT_BRACKETS_IN 10 /* 栈内 ( */ #define OPERA_PRIO_PLUS_OUT 5 /* 栈外 + */ #define OPERA_PRIO_MINUS_OUT 5 /* 栈外 - */ #define OPERA_PRIO_MULTIPLY_OUT 3 /* 栈外 * */ #define OPERA_PRIO_DIVISION_OUT 3 /* 栈外 / */ #define OPERA_PRIO_LEFT_BRACKETS_OUT 1 /* 栈外 ( */ #define OPERA_PRIO_RIGHT_BRACKETS_OUT 10 /* 栈外 ) */ #define OPERA_PRIO_ERR -1 #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "lstack.h" void InitStack(PStack ps) { assert(ps != NULL); ps->next = NULL; } //入栈,头插 bool Push(PStack ps,int val)//O(1) { SNode *p = (SNode *)malloc(sizeof(SNode )); p->data = val; p->next = ps->next; ps->next = p; return true; } bool IsEmpty(PStack ps) { return ps->next == NULL; } //获取栈顶元素的值,但不删除 bool GetTop(PStack ps,int *rtval)//O(1) { if(IsEmpty(ps)) { return false; } *rtval = ps->next->data; return true; } //获取栈顶元素的值,且删除 bool Pop(PStack ps,int *rtval)//O(1) { if(IsEmpty(ps)) { return false; } SNode *p = ps->next; ps->next = p->next; *rtval = p->data; free(p); return true; } void Clear(PStack ps) { Destroy(ps); } void Destroy(PStack ps) { SNode *p; while(ps->next != NULL) { p = ps->next; ps->next = p->next; free(p); } } int Priority(char opera, bool InStack) { int prio = OPERA_PRIO_ERR; if(InStack) { switch(opera) { case '+': prio = OPERA_PRIO_PLUS_IN; break; case '-': prio = OPERA_PRIO_MINUS_IN; break; case '*': prio = OPERA_PRIO_MULTIPLY_IN; break; case '/': prio = OPERA_PRIO_DIVISION_IN; break; case '(': prio = OPERA_PRIO_LEFT_BRACKETS_IN; break; default: prio = OPERA_PRIO_ERR; break; } } else { switch(opera) { case '+': prio = OPERA_PRIO_PLUS_OUT; break; case '-': prio = OPERA_PRIO_MINUS_OUT; break; case '*': prio = OPERA_PRIO_MULTIPLY_OUT; break; case '/': prio = OPERA_PRIO_DIVISION_OUT; break; case '(': prio = OPERA_PRIO_LEFT_BRACKETS_OUT; break; case ')': prio = OPERA_PRIO_RIGHT_BRACKETS_OUT; break; default: prio = OPERA_PRIO_ERR; break; } } return prio; } void MidtoLast(char *last,const char *mid) { SNode s; InitStack(&s); int i = 0;//last下标 int prioIn;//栈内符号优先级 int prioOut;//栈外符号优先级 int tmp; while(*mid != '\0') { if(isdigit(*mid)) { last[i++] = *mid++; } else //运算符 { if(IsEmpty(&s))//栈空 { Push(&s,*mid++); } else //栈不空,比较优先级 { GetTop(&s,&tmp); prioIn = Priority(tmp,true); prioOut = Priority(*mid,false); if(prioOut < prioIn)//栈外优先级高,进栈 { Push(&s,*mid++); } else if(prioOut > prioIn)//栈外优先级低,出栈 { Pop(&s,&tmp); last[i++] = (char)tmp; } else//优先级相等,()匹配,直接删除 { mid++; Pop(&s,&tmp); } } } } while(!IsEmpty(&s)) { Pop(&s,&tmp); last[i++] = (char)tmp; } last[i] = '\0'; } int main() { char *mid = "3+4*(5-3)/(4-2)"; char last[100]; MidtoLast(last,mid); printf("%s\n%s\n",mid,last); return 0; }