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

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;
}
 
相关推荐
hnjzsyjyj12 分钟前
洛谷 B3622:枚举子集(递归实现指数型枚举)← DFS
数据结构·dfs
sakiko_16 分钟前
UIKit学习笔记2-组件嵌套、滚动视图等
笔记·学习·objective-c·swift·uikit
2501_943205051 小时前
【182期】一键扫描C盘空间占用并清理!
经验分享
蛋白界小百灵1 小时前
纳米抗体技术全解析:从文库构建到亲和力成熟的关键策略
经验分享·科技·学习·健康医疗·业界资讯·卡梅德生物
聆风吟º1 小时前
【C标准库】深入理解C语言strcat函数:字符串拼接的利器
c语言·开发语言·strcat·库函数
Alice-YUE2 小时前
【JS高频八股】什么是闭包?
开发语言·javascript·笔记·学习
宵时待雨2 小时前
linux笔记归纳3:linux开发工具
linux·运维·笔记
datascome2 小时前
文章自动采集发布到Discuz网站技巧
经验分享·爬虫·数据采集·discuz·网站内容批量发布
qiqsevenqiqiqiqi2 小时前
MT2048三连 暴力→数学推导→O (n) 优化
数据结构·c++·算法
码之气三段.2 小时前
十五届山东ccpc省赛补题(update)
数据结构·c++·算法