【数据结构】栈和队列的定义和基本操作 |入栈 |出栈 |入队 |出队 |顺序栈 |链栈 |循环队列 |链队列

📖专栏文章:数据结构学习笔记
🪪作者主页:格乐斯

前言

栈和队列的定义和基本操作(初始化入栈出栈,入队出队)
顺序栈、链栈
顺序队列、循环队列、链队列

定义:

  • 先进后出(LIFO)
  • 只能在表的一端插入或删除的线性表。
  • 表的尾端为栈顶(top),头端为栈底(base)
  • 没有元素的栈称为空栈

顺序栈

顺序栈的表示

  • 地址连续的存储单元存放自栈底到栈顶的元素。栈底元素存在低地址

创建栈表

typedef SElemType int;
typedef struct
{
    //栈底
    SElemType *base;
    //栈顶
    SElemType *top;
    //栈容量
    int StackSize;
}SqStack;
SqStack S;

顺序栈的基本操作

  • 初始化
int MAXSIZE = 100;
bool InitStack(SqStack &S)
{
    //创建栈空间
    S.base= new SElemType Stack[MAXSIZE];
    if (!S.base) return false;
    S.StackSize = MAXSIZE;
    S.top=S.base;
    return true;
}
  • 入栈
bool Push(SqStack &S,SElemType e)
{
    if(S.top-S.base==S.StackSize) return false;
    *S.top=e;
    S.top++;
    return true;
}
  • 出栈
bool Pop(SqStack &S,SElemType &e)
{
    if(S.base==S.top) return false;
    S.top--;
    e= *S.top;
    return true;
} 

链栈

链栈的表示

  1. 与链表的形式相同,链栈的元素也是通过结点的指针相关联

  2. 栈顶指针就是头指针

  3. 插入和删除操作在栈顶完成,所以不需要头结点访问整个链栈

  4. 几乎不存在满栈的情况

创建链栈

typedef SElemType int;
typedef struct StackNode
{
    //数据域
    int data;
    //指针域
    struct StackNode *next;
}StackNode,*LinkStack

链栈的基本操作

  • 初始化
void InitLinkStack(LinkStack &S)
{
    S->next=null;
}
  • 求链栈的长度
int StackLength(LinkStack &S)
{
    int len=0;
    StackNode *cur=S;
    while(cur!=NULL)
    {
        len++;
        cur=cur->next;
    }
    return len;
} 
  • 入栈
void push(LinkStack &S,SElemType e)
{
    //构造一个结点p,并给结点的数据域赋值
    StackNode *p=new StackNode;
  	p->data=e;
    p->next=NULL;
    if(S==NULL)
    {
        //如果栈为空,那直接将栈顶指针修改为p
        S=p;
    }
    else
    {
        //如果不为空,就先将结点p放在栈顶结点前面,再改变栈顶指针
        p->next=S;
        S=p;
    }
}
  • 出栈
bool pop(LinkStack &S,SElemType &e)
{
    StackNode *p=new StackNode;
    if(S==NULL) return false;
    else
    {
        //栈不为空,去除栈顶元素,栈顶指针后移一位,删除栈顶结点
        p=s;
        e=p->data;
        s=s->next;
        delete p;
    }
    return true;
}

共享栈

有两个相同类型的栈时,采用共享栈最大限度地利用空间进行操作;共享栈既可以使用自己的空间,也可以使用对方的空间

 0                                       MAXSIZE-1
 ====================== ======================  
^                     ^ ^                     ^
1号栈底           1号栈顶 2号栈顶              2号栈底

构造共享栈

typedef SElemType int;
typedef struct
{
    SElemType s1[MAXSIZE];
    SElemType s2[MAXSIZE];
    int top1;
    int top2;
}SharedStack;
SharedStack S;

共享栈的基本操作

  • 判空:
bool isEmpty(SharedStack S)
{
    if(S.top1== -1 && S.top2 == MAXSIZE) return true;
    return false;
}
  • 判满:
bool isFull(SharedStack S)
{
    if(S.top1+1 == S.top2) return true;
    return false;
}
  • 进栈:
//1号栈入栈
bool Push1(SharedStack &S,SElemType e)
{
    if(isFull(S)) return false;
    S.top1 ++;
    S.s1[S.top1]=e;
    return true;
}
//2号栈入栈
bool Push2(SharedStack &S,SElemType e)
{
    if(isFull(S)) return false;
    S.top2 --;
    S.s2[S.top2]=e;
    return true;
}
  • 出栈:
//1号栈出栈
bool Pop1(SharedStack &S,SElemType &e)
{
    if(isFull(S)) return false;
    e=S.s1[S.top1];
    S.top1 --;
    return true;
}
//2号栈出栈
bool Pop1(SharedStack &S,SElemType &e)
{
    if(isFull(S)) return false;
    e=S.s2[S.top2];
    S.top2 ++;
    return true;
}

队列

定义:

先进先出(FIFO)的线性表,在表的一端插入,另一端删除

顺序队列

构造顺序队列

typedef QElemType int;
typedef struct 
{
    int MAXSIZE=100;
    QElemType front;
    QElemType rear;
    QElemType data[MAXSIZE];
}SQueue;
SQueue SQ;

顺序栈的基本操作

  • 初始化
bool InitSQueue(SQueue &SQ)
{
    if(!SQ.data) return false;
    SQ.rear=SQ.front=0;
    return true;
}
  • 入队
bool EnQueue(SQueue &SQ,QElemType e)
{
    if(SQ.rear==SQ.MAXSIZE-1) return false;
    SQ.data[rear]=e;
    rear++;
    return true;
}
  • 出队
bool DeQueue(SQueue &SQ,QElemType &e)
{
    if(SQ.rear==0) return false;
    e=SQ.data[front];
    front++;
    return true;
}
  • 打印队列
bool PrintQueue(SQueue &SQ)
{
    if(SQ.rear==0) return false;
    int qsize=SQ.rear-SQ.front;
    printf("打印队列:\n");
    for(int i=0;i<qsize;i++)
    {
        if(i==0) printf("队首|");
        printf("%d ",SQ.data[i]);
        if(i==qsize-1) printf("|队尾");
    }
    return true;
}

循环队列

定义

循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。

构造循环队列

typedef QElemType int;
typedef struct 
{
    int MAXSIZE=100;
    QElemType front;
    QElemType rear;
    QElemType data[MAXSIZE];
}CcQueue;
CcQueue CQ;

循环队列的基本操作

  • 初始化
bool InitCcQueue(CcQueue &CQ)
{
    if(!SQ.data) return false;
    CQ.rear=CQ.front=0;
    return true;
}
  • 判断队列长度
int getLength(CcQueue &CQ)
{
    return (CQ.rear+CQ.MAXSIZE-CQ.front)%CQ.MAXSIZE;
}
  • 入队
bool EnQueue(CcQueue &CQ,QElemType e)
{
    //判满
    if((CQ.rear+1)%MAXSIZE==CQ.front) return false;
    CQ.data[CQ.rear]=e;
    CQ.rear=(CQ.rear+1)%CQ.MAXSIZE;
    return true;
}
  • 出队
bool DeQueue(CcQueue &CQ,QElemType &e)
{
    //判空
    if(CQ.rear==CQ.front) return false;
    CQ.front=(CQ.front+1)%CQ.MAXSIZE;
    e=CQ.data[CQ.front];
    return true;
}
  • 打印队列
bool PrintQueue(SQueue &SQ)
{
    //判空
    if(CQ.rear==CQ.front) return false;
    int qsize=getLength(SQ);
    printf("打印队列:\n");
    for(int i=0;i<qsize;i++)
    {
        if(i==0) printf("队首|");
        printf("%d ",CQ.data[i]);
        if(i==qsize-1) printf("|队尾");
    }
    return true;
}

链队列

定义

使用链式存储结构的队列,称为链队列

构造链队列管理结构

//链式队列管理结构
typedef QElemType int;
typedef struct 
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
LinkQueue LQ;

创建链队列结点类型

typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

链队列的基本操作

  • 初始化
bool InitLinkQueue(LinkQueue &LQ)
{
    //生成头结点
    LQ.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
    if(!LQ.front) return false;
    //将头结点的指针域置为空
    LQ.front->next=NULL;
    return true;
}
  • 判断队列长度
int getLength(LinkQueue &LQ)
{
    int len=0;
    QNode *p=LQ.front->next;
    while(p)
    {
        len++;
        p=p->next;
    }
    return len;
}
  • 入队
//新元素e 入队
bool EnQueue(LinkQueue &LQ,QElemType e)
{
    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) return false; 
    p.data=e;  //新元素存入新结点
    LQ.rear->next=p;  //将队尾结点与新结点建立连接
    p->next=NULL;   //新结点的指针域置为空
    LQ.rear=p;  //队尾指针指向新结点  
}
  • 出队
bool DeQueue(LinkQueue &LQ,QElemType &e)
{
    if(!LQ.front->next) return false;
    e=LQ.front->next->data;
    LQ.front->next=LQ.front->next->next;
    return true;
}
  • 打印队列
bool PrintQueue(LinkQueue LQ)
{
    if(!LQ.front->next) return false;
    QNode *p=LQ.front->next;
    while(p)
    {
        printf("%d ",p->data);
    }
    return true;
}

总结

本文主要介绍了栈和队列的定义和基本操作(初始化入栈出栈,入队出队)


文章到这结束啦,感谢阅读~

如果文章的论述或代码等出现错误,欢迎前来指正!

如果你觉得文章写的还不错,记得点赞收藏评论三连~ ❤

img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值