队列(先进先出)
队列的定义:只允许在一端进行插入操作,而在另一端进行删除操作的线性表
直接使用数组容易造成假性溢出,为了解决假性溢出问题,使用头尾相连的循环队列
循环队列(核心是利用取余实现循环)
定义:把队列头尾相接的顺序存储结构叫做循环队列
typedef struct {
int data[n];
int head;
int tail;
}a;
初始化
a.tail=0;
a.head=0;
(1~n)实际存储个数为n-1;留一个位置判断队满或者队空
队空:tail==head(head是队头的前一个,tail是对尾)
队满:tail+1==head;
入队:tail=(tail+1)%n;
if((a.tail+1)%n==a.head)
return 0;//队满
a.data[a.tail]=x;//将x存入
a.tail=(a.tail+1)%n;//更新尾指针
出队:head=(head+1)%n;
if((a.tail==a.head)
return 0;//队空
x=a.data[a.head];//将x存入
a.data[a.head]=0;//可以不写
a.head=(head+1)%n;//更新头指针
元素个数:(tail-head+n)%n;
链队列
定义
typedef struct Node
{
int data;
struct NOde* next;
}snode;
typedef struct
{
snode *head;
snode*tail;
}dueil;
入队
构建一个新节点,修改队尾指针使其指向新节点
snode* p=(snode*)malloc(sizeof(snode));
if(p!=NULL)
{
p->data=x;
p->next=NULL:
Q->tail->next=p;
q->tail=p;
}
出队
snode* p;
if(Q->head==Q->tail)
return 0;
p=Q->head->next;
x=p->data;
Q->head->next=p->next;
if(Q-tail==p)
Q->head=Q->tail;
free(p);
栈(先进后出)
栈的定义
限定在表尾进行插入删除操作的线性表
顺序栈
栈的结构定义
typedef struct
{
int data[1000];//数据类型可自己选择
int top;//栈顶
}zan
进栈
zan a;
if(a->top>=1000)
return 0;//栈满
a->top++;
a->data[a->top]=x;//x即所赋值
出栈
zan a;
if(a->top>=1000)
return 0;//栈满
a->data[a->top]=0;//
a->top--;
共享栈
定义:俩个栈共享一片储存空间 ,这片空间不属于任何一个栈
结构体定义
typedef struct
{
int data[1000];//数据类型可自己选择
int top1;//栈一的顶
int top2;//栈二的顶
}zan
初始化
zan a;
a.top1=-1;
a.yop2=1000
栈空 top1==-1&&top==1000;
栈满 top2-top1=1//俩栈顶相邻
进出栈
-
进行危险判断(进栈判栈满,出栈判栈空)
-
进出栈 (建议画图)
进栈 a->data[++top1]=x; a->data[--top2]=x;
出栈 x=s->data[top1--]; x=s->data[top2++];
链栈(栈的链式存储结构)
数据结构定义
typedef struct list
{
int data;
struct list*next;
}snode;
初始化
snode *s=NULL;//s就栈顶元素
入栈
snode *p;
p->data=x;
p->next=S;
S=p;
出栈
snode*p;
if(s==NULL)
return 0;//栈空
x=s->data;
p=s;
s=s->next;
free(p);
后缀表达式
核心注意点 ,函数atio,二维数组判断首个字符
//思路:将数字存入栈,若遇到运算字符取出上面两个数字运算将得到数字再次存入
//问题在于负数特判比较麻烦;
struct zan
{
int data[100000];
int top ;
}s;//创建栈
void jin(int x)
{
s.top++;
s.data[s.top]=x;
}//入栈,这里可以加个判断栈满,但是没必要,判出来也没有办法处理,直接把数组开大一点
int chu(char t)
{
int z;
int x,y;
x=s.data[s.top];
// return x;
s.data[s.top]=0;
s.top--;
y=s.data[s.top];
// return y;
s.data[s.top]=0;
s.top--;//出栈,判空同理
if(t =='+')//计算
{
z=x+y;
}
else if(t=='-')
{
z=y-x;
}
else if(t=='*')
{
z=x*y;
}
else if(t=='/')
{
z=y/x;
}
return z;
}
int evalRPN(char ** a, int n){
s.top=0;
for(int i=0;i<n;i++)
{
int w=strlen(a[i]);//判断是否为负数与负号区别若不判断,下面会把负数跳过,当负号计算
if(w==1&&(a[i][0]=='+'||a[i][0]=='-'||a[i][0]=='/'||a[i][0]=='*'))
{
int z;
z= chu(a[i][0]);
jin(z);
}
else
{
int t=atoi(a[i]);
jin(t);
}
}
return s.data[s.top];
}