【C语言基础】栈和队列

一、栈

先进后出 FILO (First In Last Out)
只允许在一端进行插入或删除操作的线性表

入栈:放入元素
出栈:拿出元素

在这里插入图片描述

1 线性栈

入栈:
S.data[++S.top] = 1 : 表示 S.top=S.top+1 ; S.data[S.top] = 1(√)
S.data[S.top++] = 1 : 表示 S.data[S.top] = 1 ; S.top=S.top+1

出栈:
S.data[S.top- -] = 1 : 表示 x = S.data[S.top] ; S.top=S.top-1 (√)
S.data[- -S.top] = 1 : 表示 S.top=S.top-1 ; x = S.data[S.top];

1.1 代码实现

typedef int ElemType;
typedef struct {
    ElemType data[MaxSize];
    int top;//栈顶 满栈 MaxSize-1 = S.top
}SqStack;

//修改操作传引用

//1. 初始化栈
void InitStack(SqStack& S)
{
    S.top = -1;//栈顶
}

//2. 判断是否为空
bool StackEmpty(SqStack S)
{
    if (-1 == S.top)
    {
        return true;
    }
    else {
        return false;
    }
}

//3. 入栈
bool Push(SqStack& S, ElemType x)
{
    //判断是否满栈
    if (S.top == MaxSize - 1)
    {
        return false;
    }
    S.data[++S.top] = x;//先top加加,再赋值
    return true;
}

//4. 获取栈顶元素
bool GetTop(SqStack S, ElemType& m)
{
    if (StackEmpty(S))
    {
        return false;
    }
    m = S.data[S.top];//保存到m
    return true;
}

//5. 出栈
bool Pop(SqStack& S, ElemType& m)
{
    if (StackEmpty(S))
    {
        return false;
    }
    m = S.data[S.top--];//m=S.data[S.top];S.top=S.top-1;
    return true;
}

2 链栈

链表实现栈,规定所有操作都是在单链表的表头进行的。
链栈不存在栈满上溢的情况。

请添加图片描述
请添加图片描述
请添加图片描述

2.1 代码实现

//栈的链式存储结构
//构造节点
typedef struct StackNode {
    ElemType data;
    struct StackNode* next;
}StackNode, * LinkStackPtr;
//构造链栈
typedef struct LinkStack {
    LinkStackPtr top;
    int count;
}LinkStack;
//这里规定链栈没有头节点,Lhead指向栈顶元素
//1.插入元素   e为新的栈顶元素
bool Push(LinkStack* S, ElemType e) {
    LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
    p->data = e;
    p->next = S->top;    //把当前的栈顶元素赋值给新节点的直接后继
    S->top = p; //将新的结点S赋值给栈顶指针
    S->count++;
    return true;
}

//2. 若栈不空,则删除S的栈顶元素,用e返回其值
bool Pop(LinkStack* S, ElemType* e) {
    LinkStackPtr p;
    if (StackEmpty(*S)) {
        return false;
    }
    *e = S->top->data;
    p = S->top; //将栈顶结点赋值给p
    S->top = S->top->next;  //使得栈顶指针下移一位,指向后一结点
    free(p);    //释放结点p
    S->count--;
    return true;
}

二、队列

先进先出(FIFO)
队列满: (Q.rear+1)%MaxSize == Q.front

1 顺序队列

初始状态(队空条件):Q.front == Q.rear == 0。
进队操作:队不满时,先送值到队尾元素,再将队尾指针加1。
出队操作:队不空时,先取队头元素值,再将队头指针加1。
在这里插入图片描述

2 循环队列

初始:Q.front = Q.rear=0。
队首指针进1:Q.front = (Q.front + 1) % MaxSize。
队尾指针进1:Q.rear = (Q.rear + 1) % MaxSize。
队列长度:(Q.rear - Q.front + MAXSIZE) % MaxSize。

请添加图片描述

2.1 代码实现

#define MaxSize 50
typedef int ElemType;
//循环队列
typedef struct {
    ElemType data[MaxSize]; //只能存MaxSize-1个元素
    int front, rear;// 队头队尾
}SqQueue;

// 1.队列初始化
void InitQueue(SqQueue& Q)
{
    Q.front = Q.rear = 0;
}
//2. 判断队列是否为空
bool isEmpty(SqQueue Q)
{
    return Q.rear == Q.front;
}
//3. 入队
bool EnQueue(SqQueue& Q, ElemType x)
{
    if ((Q.rear + 1) % MaxSize == Q.front)//队列为满
    {
        return false;
    }
    Q.data[Q.rear] = x;//入队
    Q.rear = (Q.rear + 1) % MaxSize;//队尾位置(指向可以放元素的位置
    return true;
}
//4. 出队
bool DeQueue(SqQueue& Q, ElemType& x)
{
    if (Q.rear == Q.front)//是否为空
    {
        return false;
    }
    x = Q.data[Q.front];//出队
    Q.front = (Q.front + 1) % MaxSize;
    return true;
}

3 链式队列

请添加图片描述
请添加图片描述

3.1 代码实现

typedef int ElemType;
typedef struct LinkNode {
    ElemType data;
    struct LinkNode* next;
}LinkNode;
typedef struct {
    LinkNode* front, * rear;//头尾指针
}LinkQueue;//

//初始化
void InitQueue(LinkQueue& Q)
{
    Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
    Q.front->next = NULL;
}
//入队  有头结点的链表
void EnQueue(LinkQueue& Q, ElemType x)
{
    LinkNode* pnew = (LinkNode*)malloc(sizeof(LinkNode));
    pnew->data = x;
    pnew->next = NULL;//next为null
    Q.rear->next = pnew;//尾指针指向pnew
    Q.rear = pnew;//rear指向新的尾部
}
//出队
bool DeQueue(LinkQueue& Q, ElemType& x)
{
    if (Q.rear == Q.front)//队列为空
    {
        return false;
    }
    //出队即相当于删除一个节点,从头部删除
    LinkNode* q = Q.front->next;//拿到第一个节点
    x = q->data;
    Q.front->next = q->next;//让第一个节点断链
    if (Q.rear == q)//如果删除了一个节点以后只有一个节点
    {
        Q.rear = Q.front;//指向最后一个节点
    }
    free(q);
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值