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

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 天前
图编译优化全链路:CANN graph-engine 仓库技术拆解
c语言
张张努力变强1 天前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
wWYy.1 天前
数组快排 链表归并
数据结构·链表
JustDI-CM1 天前
AI学习笔记-提示词工程
人工智能·笔记·学习
爱写bug的野原新之助1 天前
加密摘要算法MD5、SHA、HMAC:学习笔记
笔记·学习
C++ 老炮儿的技术栈1 天前
VS2015 + Qt 实现图形化Hello World(详细步骤)
c语言·开发语言·c++·windows·qt
Once_day1 天前
C++之《Effective C++》读书总结(4)
c语言·c++·effective c++
李斯啦果1 天前
【PTA】L1-019 谁先倒
数据结构·算法
晓13131 天前
第七章 【C语言篇:文件】 文件全面解析
linux·c语言·开发语言
梵刹古音1 天前
【C语言】 指针基础与定义
c语言·开发语言·算法