栈和队列及相关习题

队列(先进先出)

队列的定义:只允许在一端进行插入操作,而在另一端进行删除操作的线性表

直接使用数组容易造成假性溢出,为了解决假性溢出问题,使用头尾相连的循环队列

循环队列(核心是利用取余实现循环)

定义:把队列头尾相接的顺序存储结构叫做循环队列
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//俩栈顶相邻

进出栈

  1. 进行危险判断(进栈判栈满,出栈判栈空)

  2. 进出栈 (建议画图)

    进栈 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];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值