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

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;
}
 
相关推荐
郝学胜-神的一滴1 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
Lzh编程小栈2 小时前
【嵌入式底层】SPI超透彻详解:通信原理、四线结构、四种模式、寄存器底层 + 面试全集
c语言·stm32·单片机·面试·职场和发展
疯狂打码的少年2 小时前
【数据结构】二叉树的性质(五大性质+计算)
数据结构·笔记·算法
wabs6663 小时前
关于图论【A*算法 | 卡码网127.骑士的攻击的思考】
数据结构·算法·图论·卡码网·广搜的改进版
凉茶钱3 小时前
【数据结构】堆的应用
c语言·数据结构
Capricorn19883 小时前
知芽研究问题看板无法推进?从孵化区到笔记的机制排查指南
大数据·论文阅读·人工智能·笔记·学习方法·论文笔记
闪闪发亮的小星星3 小时前
相机脱靶量VS精跟踪精度
笔记
皖山文武3 小时前
逻辑代数基础学习笔记--概述
笔记·学习·机器学习
间歇性努力持续性发呆的野生快乐选手4 小时前
栈的性质(进栈,出栈,访问)
数据结构·c++
m0_547486664 小时前
《数据结构与算法》全套PPT课件2026(中国海洋大学)
数据结构·算法