栈与队列:数据结构入门指南

1.栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

1.2栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小

复制代码
c 复制代码
// 栈结构初始化与销毁

void STInit(ST* pst)
{
    assert(pst);
    pst->a = NULL;
    pst->top = 0;        // top指向栈顶元素的下一个位置
    pst->capacity = 0;
}

void STDestroy(ST* pst)
{
    assert(pst);
    free(pst->a);
    pst->a = NULL;
    pst->top = pst->capacity = 0;
}

// 栈操作函数

void STPush(ST* pst, STDataType x)
{
    assert(pst);
    
    // 检查并处理容量不足的情况
    if (pst->top == pst->capacity)
    {
        int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
        STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
        if (!tmp)
        {
            perror("realloc fail");
            return;
        }
        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    
    pst->a[pst->top++] = x;
}

void STPop(ST* pst)
{
    assert(pst && pst->top > 0);
    --pst->top;
}

STDataType STTop(ST* pst)
{
    assert(pst && pst->top > 0);
    return pst->a[pst->top - 1];
}

bool STEmpty(ST* pst)
{
    assert(pst);
    return pst->top == 0;
}

int STSize(ST* pst)
{
    assert(pst);
    return pst->top;
}
 

2.队列

2.1队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

2.2队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低。

采用链表实现队列的方法与实现栈的方法类似,分别用两个指针指向队列的首元素与尾元素,如下图所示。用pHead来指向队列的首元素,用pEnd来指向队列的尾元素。

c 复制代码
// 初始化队列
void QueueInit(Queue* pq)
{
    assert(pq);
    pq->phead = NULL;
    pq->ptail = NULL;
    pq->size = 0;
}

// 销毁队列
void QueueDestroy(Queue* pq)
{
    assert(pq);
    QNode* cur = pq->phead;
    while (cur)
    {
        QNode* next = cur->next;
        free(cur);
        cur = next;
    }
    pq->phead = pq->ptail = NULL;
    pq->size = 0;
}

// 入队操作
void QueuePush(Queue* pq, QDataType x)
{
    assert(pq);
    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    if (!newnode)
    {
        perror("malloc fail");
        return;
    }
    
    newnode->next = NULL;
    newnode->val = x;
    
    if (!pq->ptail)
    {
        pq->phead = pq->ptail = newnode;
    }
    else
    {
        pq->ptail->next = newnode;
        pq->ptail = newnode;
    }
    pq->size++;
}

// 出队操作
void QueuePop(Queue* pq)
{
    assert(pq && pq->size > 0);
    
    if (!pq->phead->next)  // 单节点情况
    {
        free(pq->phead);
        pq->phead = pq->ptail = NULL;
    }
    else  // 多节点情况
    {
        QNode* next = pq->phead->next;
        free(pq->phead);
        pq->phead = next;
    }
    pq->size--;
}

// 获取队首元素
QDataType QueueFront(Queue* pq)
{
    assert(pq && pq->phead);
    return pq->phead->val;
}

// 获取队尾元素
QDataType QueueBack(Queue* pq)
{
    assert(pq && pq->ptail);
    return pq->ptail->val;
}

// 获取队列大小
int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}

// 判断队列是否为空
bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->size == 0;
}
 
相关推荐
丝斯201111 小时前
AI学习笔记整理(57)——大模型微调相关技术
人工智能·笔记·学习
StandbyTime11 小时前
C语言学习-菜鸟教程C经典100例-练习43
c语言
学嵌入式的小杨同学11 小时前
【嵌入式 Linux 实战 1】Ubuntu 环境搭建 + 目录结构详解:嵌入式开发入门第一步
linux·c语言·开发语言·数据结构·vscode·vim·unix
源代码•宸11 小时前
Leetcode—47. 全排列 II【中等】
经验分享·后端·算法·leetcode·面试·golang·深度优先
Ada's11 小时前
【计算机基础系列】001:计算机科学与技术
数据结构
17(无规则自律)12 小时前
【CSAPP 读书笔记】第一章:计算机系统漫游
linux·c语言·arm开发·嵌入式硬件·学习·ubuntu
WYH28712 小时前
为什么在cubeide里勾选了can1,生成的工程里没有can.c?
c语言·开发语言
曾浩轩12 小时前
C语言学习记录——BC113 数字三角形
c语言·学习
梦幻精灵_cq12 小时前
《双征color》诗解——梦幻精灵_cq对终端渲染的数据结构设计模型式拓展
数据结构·python
四谎真好看12 小时前
JavaWeb学习笔记(Day08+Day09)之Mybatis入门+基础操作
笔记·学习·学习笔记·javaweb