带你玩转栈和队列

 

栈接口的实现,直接上代码

这里讲解下有的人是把top给成-1的,栈顶指针 top 被初始化为 -1,表示栈中没有任何元素。当向栈中插入第一个元素时,我们需要将 top 的值加 1,然后将该元素存储在数组中 top 所指向的位置。此时,top 的值为 0,表示栈中有一个元素。因此,栈中有一个元素是因为插入了第一个元素。所以这里要取分一下.top给成0还是-1,根据场景应用给成多少。

栈函数的声明:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>


typedef int STDataType;
typedef struct Stack
{
    STDataType* a;
    int top;
    int capacity;
}ST;

void STInit(ST* pst);
void STDestory(ST* pst);

void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

bool STEmpty(ST* pst);
int STSize(ST* pst);
int STTop(ST* pst);


栈的初始化:

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

栈的销毁:

void STDestory(ST* pst)
{
    assert(pst);

    free(pst->a);
    pst->a = NULL;
    pst->capacity = pst->capacity = 0;
}

栈里增加元素:

void STPush(ST* pst, STDataType x)
{
    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 == NULL)
        {
            perror("realloc fail");
            return;
        }
        pst->a = tmp;
        pst->capacity = newCapacity;
    }

    pst->a[pst->top] = x;
    pst->top++;
}

栈里删除元素:

void STPop(ST* pst)
{
    assert(pst);
    assert(!STEmpty(pst));

    pst->top--;
}

返回栈顶元素:

STDataType STTop(ST* pst)
{
    assert(pst);

    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;
}

栈函数的简单实现:

#include"stack.h"

void TestStack()
{
    ST st;
    STInit(&st);
    STPush(&st, 1);
    STPush(&st, 2);
    STPush(&st, 3);
    STPush(&st, 4);
    while (!STEmpty(&st))
    {
        printf("%d ", STTop(&st));
        STPop(&st);
    }
    STDestory(&st);
}

int main()
{
    TestStack();
    return 0;
}

总结:

  • 栈是一种简单但非常有用的数据结构,掌握它的基本概念、操作和实现方式对于编程学习和刷题,后面的面试都非常重要。

第二部分

队列:FIFO(First Input First Output)

定义:

        队列是一种特殊的线性结构,只允许在队列的首部进行删除操作(相当于排在最前面的先买票),这称为出队(即最先来的人买完票就应该走),而在队列的尾部进行插入(后来者排对在队尾)操作,这称为入队。
 

队列图解:

 

队列函数的声明:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
    struct QDataType* next;
    QDataType data;
}QNode;

typedef struct Queue
{
    QNode* phead;
    QNode* tail;
    int size;
}Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);

队列函数的实现:

队列的初始化:

#include"Queue.h"

void QueueInit(Queue* pq)
{
    assert(pq);
    pq->phead = NULL;
    pq->tail = NULL;
    pq->size = 0;
}
队列的销毁:

void QueueDestroy(Queue* pq)
{
    assert(pq);
    
    QNode* cur = pq->phead;
    while (cur)
    {
        QNode* next = cur;
        free(cur);
        cur = next;
    }

    pq->phead = NULL;
    pq->tail = NULL;
    pq->size = 0;
}

队列元素的添加:

void QueuePush(Queue* pq, QDataType x)
{
    assert(pq);

    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    if (newnode == NULL)
    {
        perror("malloc fail");
        return;
    }
    newnode->next = NULL;
    newnode->data = x;

    if (pq->tail == NULL)
    {
        assert(pq->phead == NULL);
        pq->phead = pq->tail = newnode;
    }

    else
    {
        pq->tail->next = newnode;
        pq->tail = newnode;
    }
    
    pq->size++;
}
队列元素的删除:

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    if (pq->phead->next == NULL)
    {
        free(pq->phead);
        pq->phead = pq->tail = NULL;
    }
    else
    {
        QNode* next = pq->phead->next;
        free(pq->phead);
        pq->phead = next;
    }

    pq->size--;
}

返回队头元素:

QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    return pq->phead->data;
}

返回队尾元素:

QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    return pq->tail->data;
}

返回队列的大小:

int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}

判断队列是否为空:

bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->phead == NULL && pq->tail == NULL;
}

队列函数的简单实现:

#include"Queue.h"

TestQueue()
{
    Queue q;
    QueueInit(&q);
    QueuePush(&q, 1);
    QueuePop(&q);
    QueuePush(&q, 2);
    QueuePush(&q, 3);
    QueuePush(&q, 4);
    
    while (!QueueEmpty(&q))
    {
        printf("%d ", QueueFront(&q));
        QueuePop(&q);
    }
    printf("\n");

    QueueDestroy(&q);
}

int main()
{
    TestQueue();
    return 0;
}

总结

  1. 队列先进先出
  2. 队列为空相当于队首等于队尾
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值