【数据结构】栈和队列

文章详细介绍了栈和队列这两种数据结构的定义、功能以及C语言实现。栈是一种仅在表尾进行插入和删除的线性表,支持进栈、出栈和查看栈顶元素等操作。队列则允许在前端删除、后端插入,提供了进队、出队、查看队头和队尾元素的功能。文中还给出了具体的C语言代码示例来说明如何初始化、销毁以及操作栈和队列。
摘要由CSDN通过智能技术生成

一、栈

  1. 定义

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
  1. 功能实现

<0>头文件

#ifndef STACK_H
#define STACK_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#endif

typedef int STDataType;
typedef struct StackNode
{
    STDataType *a;
    int capacity;
    int top;//top有两种定义方式,为栈顶元素的下标或站定元素下个位置的下标
} ST;

void STInit(ST *ps);//初始化栈
void STDestroy(ST *ps);//销毁瞻
void STPush(ST *ps,STDataType x);//数据进栈
void STPop(ST *ps);//数据出栈
STDataType STTop(ST *ps);//返回栈顶数据
bool STEmpty(ST *ps);//判断栈是否为空
int STSize(ST *ps);//返回栈的大小

<1>初始化栈

void STInit(ST *ps)//初始化栈
{
    assert(ps);//一般在函数外定义结构体,在函数内初始化,这样比较简单,指针记得要判空
    //ps->a=NULL;
    ps->a=(STDataType*)malloc(sizeof(STDataType)*4);
    if(!ps->a)
    {
        perror("malloc fail");
        exit(-1);
    }
    ps->capacity=4;
    ps->top=0;//这种定义方式下top为栈顶数据的下一个位置的下标
    return;
}

<2>销毁栈

void STDestroy(ST *ps)//销毁栈
{
    assert(ps);
    free(ps->a);
    ps->a=NULL;
    ps->capacity=ps->top=0;
    return;
}

<3>数据进栈

void STPush(ST *ps,STDataType x)//数据进栈
{
    assert(ps);
    if(ps->top==ps->capacity)    //自动扩容
    {
        STDataType *tmp=(STDataType*)realloc(ps->a,sizeof(STDataType)*2*ps->capacity);
        if(!tmp)
        {
            perror("realloc fail");
            exit(-1);
        }
        ps->a=tmp;
        ps->capacity*=2;
    }
    ps->a[ps->top++]=x;
    return;
}

<4>数据出栈

void STPop(ST *ps)//数据出栈
{
    assert(ps);
    assert(!STEmpty(ps));
    ps->top--;
    return;
}

<5>返回栈顶数据

STDataType STTop(ST *ps)//返回栈顶数据
{
    assert(ps);
    assert(!STEmpty(ps));
    return ps->a[ps->top-1];
}

<6>判断栈是否为空

bool STEmpty(ST *ps)//判断栈是否为空
{
    assert(ps);
    return ps->top==0;
}

<7>返回栈的大小

int STSize(ST *ps)//返回栈的大小
{
    assert(ps);
    return ps->top;
}
  1. 实例

main函数:
#include "stack.h"

int main()
{
    ST st;
    STInit(&st);
    STPush(&st,1);
    STPush(&st,2);
    STPush(&st,3);
    printf("%d\n",STTop(&st));
    printf("size:%d\n",STSize(&st));
    STPop(&st);
    STPop(&st);
    STPop(&st);
    if(STEmpty(&st))
            printf("empty\n");
STDestroy(&st);
    return 0;
}
输出结果:

二、队列

  1. 定义

队列是一种特殊的 线性表 ,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
  1. 功能实现

<0>头文件

#ifndef QUEQUE_H
#define QUEQUE_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#endif

typedef int QDataType;
typedef struct QuequeNode
{
    QDataType data;
    struct QuequeNode *next;
} QNode;
typedef struct Queque
{
    QNode *head;//head指向链表的头节点,也是队列的队头
    QNode *tail;//tail指向链表的尾节点,也是队列的队尾
//要注意,队列前进的方向和链表的方向是相反的
    int size;
} Queque;

void QInit(Queque *pq);//初始化队列
void QDestroy(Queque *pq);//销毁队列
void QPush(Queque *pq,QDataType x);//数据进队列
void QPop(Queque *pq);//数据出队列
QDataType QFront(Queque* pq);//返回队头数据
QDataType QBack(Queque *pq);//返回队尾数据
bool QEmpty(Queque *pq);//判断队列是否为空
int QSize(Queque *pq);//计算队列大小

<1>初始化队列

void QInit(Queque *pq)//初始化队列
{
    assert(pq);
    pq->head=pq->tail=NULL;
    pq->size=0;
    return;
}

<2>销毁队列

void QDestroy(Queque *pq)//销毁队列
{
    assert(pq);
    QNode *cur=pq->head;
    while(cur)
    {
        QNode *del=cur;
        cur=cur->next;
        free(del);
    }
    pq->head=pq->tail=NULL;
    pq->size=0;
    return;
}

<3>数据进队列

void QPush(Queque *pq,QDataType x)//数据进队列
{
    assert(pq);
    QNode *newnode=(QNode*)malloc(sizeof(QNode));
    if(newnode==NULL)
    {
        perror("malloc fail");
        exit(-1);
    }
    newnode->data=x;
    newnode->next=NULL;
    if(!pq->head)
    {
        pq->head=pq->tail=newnode;
    }else
    {
        pq->tail->next=newnode;
        pq->tail=newnode;
    }
    pq->size++;
    return;
}

<4>数据出队列

void QPop(Queque *pq)//数据出队列
{
    assert(pq);
    assert(!QEmpty(pq));
    if(!pq->head->next)
    {
        free(pq->head);
        pq->head=pq->tail=NULL;
    }else
    {
        QNode *del=pq->head;
        pq->head=pq->head->next;
        free(del);
    }
    pq->size--;
    return;
}

<5>返回队头数据

QDataType QFront(Queque* pq)//返回队头数据
{
    assert(pq);
    assert(!QEmpty(pq));
    return pq->head->data;
}

<6>返回队尾数据

QDataType QBack(Queque *pq)//返回队尾数据
{
    assert(pq);
    assert(!QEmpty(pq));
    return pq->tail->data;
}

<7>判断队列是否为空

bool QEmpty(Queque *pq)//判断队列是否为空
{
    assert(pq);
    return pq->head==NULL&&pq->tail==NULL;
}

<8>返回队列大小

int QSize(Queque *pq)//计算队列大小
{
    assert(pq);
    return pq->size;
}

3.实例

main函数:
#include "queque.h"

int main()
{
    Queque q;
    QInit(&q);
    QPush(&q,1);
    QPush(&q,2);
    QPush(&q,3);
    printf("head:%dtail:%d\n",QFront(&q),QBack(&q));
    printf("size:%d\n",QSize(&q));
    QPop(&q);
    QPop(&q);
    QPop(&q);
    if(QEmpty(&q))
            printf("empty\n");
    QDestroy(&q);
    return 0;
}
输出结果:

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C.N.F

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值