首页 > 其他分享 >栈和队列专题

栈和队列专题

时间:2024-07-20 14:29:29浏览次数:8  
标签:pq return 队列 top assert 专题 pst

1,栈


1.1栈的概念及结构


栈是一种特殊的线性表,只允许在固定的一段进行插入和删除元素操作,这就很类似于我们生活中的羽毛球桶,进行数据插入和删除操作的一端叫栈顶,另一端叫栈底。栈中的元素遵守先进后出,后进先出的原则。

压栈:栈的插入

出栈,栈的删除,这两部操作都在栈顶。

静态栈可以用数组来实现,相对狭义,在实际中我们常用动态栈,本文主要写动态栈。但是是用数组来实现栈的,所以本文的TOP为int类型,指向下标。

 以下代码中 typedef int  STDataType

1.2栈的结构体

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


 1.3栈的初始化函数

 
注意top为数组下标,这里top为-1时候,之后入栈才能保证top指向正确。即top指向栈顶元素;

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


1.4栈的销毁

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

1.5栈的判空函数


bool STEmpty(ST* pst)
{
    assert(pst);
    if(pst->top==-1)
        return ture;
    else
        return false;
}


1.6栈的入栈函数

void Push(ST* pst,STDataType x)
{
    assert(pst);
    if(pst->top==pst->capacity)//扩容
{
    int newcapacity=pst->capacity== 0? 4 : pst->capacity*2;//因为初始空间可能为0
        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;
}

1.7栈的出栈函数


只移动下标,这样就访问不到;下一个下标处存在元素不影响栈的容量和其余的操作哦

void Pop(ST* pst)
{
    assert(pst);
    pst->top--;
}
1.8取栈顶元素函数
STDataType Top(ST* pst)
{
    assert(pst);
    return pst->a[pst->top];
}


1.9获取栈中元素个数

int  STSize(ST* pst){
    assert(pst);
    return (pst->top)+1;
}
1.10遍历栈的方法
void Print(ST* pst)
{
    while(!STEmpty(&s))
{    
    printf("%d",Top(&s));
    Pop(&s);
}
   STDestroy(&s);
}


1.11栈的小结


入栈和出栈顺序是一对N的关系。

栈遵循先进先出的原则。即 将栈顶新加入的数据比原先的更先出栈。

此外,做题也能让自己对栈的理解更深刻,以下是我在力扣做过的题,大家可以去做一做。

力扣"有效的括号"

二叉树的中序遍历

二叉树展开为链表

2,队列


2.1队列的概念和结构:


      队列有队头和队尾,在队头处去除元素,在队尾处加入新元素。

队列可以用来保持公平,在生活中理解可以使我们更深刻。比如商场中的抽号,排队小程序等,在过程中,按下按钮后,会显示前面有几个人,后面的人继续排队时,会在队尾处+1,而前面的人刷完自己的号后,后面的人排队号就会-1。队尾的号减去队头的号即为中间有几个人。

2.2队列的结构体


此处的队列实现使用链表较好,可以是单链表,也可以是双链表,因为队列是连续的,在两端进行修改。单链表的第一个有效节点可以记录为队头.

用链表来实现队列,那么就有一个问题,就是如果我们把节点作为形参的时候, 

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
    QNode* phead;
    QNode* ptail;
    int size;
}Queue;

2.3入队函数


队尾插入

void QueuePush(Queue*pq,QDataType x)
{
    assert(pq);
    QNode* newNode = (QNode*)malloc(sizeof(QNode));
    if(!newNode)
{
    printf("malloc fail!");
}
    newNode->val=x;
    newNode->next=NULL;
if(pq->tail==NULL)
{
pq->phead=pq->ptail=newNode;
}else{
    pq->ptail->next=newNode;
    pq->ptail=newNode;
}
    pq->size++;
    return;
}

2.4出队函数


队头出队

void QueuePop(Queue* pq)
{
  assert(pq);
  assert(pq->size);
  if(pq->phead->next==NULL)
{
    free(pq->phead);
    pq->phead=pq->ptail=NULL;
}else{
  pq->phead=pq->phead->next;
  free(pq->phead);
  pq->size--;}
  return;  
}


2.5队列初始化函数


void QueueInit(Queue *pq)
{
assert(pq);
pq->phead=NULL:
pa->ptail=NULL;
pa->size=0;
}


2.6取队列的队尾元素

QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(pq->phead);
    return pq->phead->val;
}


2.7取队列的队头元素

QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(pq->ptail);
    return pq->ptail->val;
}


2.8队列的判空函数

bool QueueEmpty(Queue *pq)
{
    assert(pq);
    if(pq->size==0)
    return true;
    else
    return false;
}


2.9队列的元素个数

QDataType QueueNum(Queue *pq)
{    
    assert(pq);
    return pq->size;
}


2.10队列的销毁函数

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


2.11队列的遍历函数

void QueuePrint(Queue* pq)
{
    assert(pq);
    while(!QueueEmpty(pq))
{
    printf("%d  ",QueueFront(pq));
    QueuePop(pq);
}
    printf("\n");
    return;
}


经典例题
这两题应用范围基本没有,但可以让我们更好的理解栈和队列。

队列实现栈

栈实现队列

标签:pq,return,队列,top,assert,专题,pst
From: https://blog.csdn.net/2301_80873677/article/details/140491337

相关文章

  • 【大数据专题】Flink题库
    1.简述什么是ApacheFlink?ApacheFlink是一个开源的基于流的有状态计算框架。它是分布式地执行的,具备低延迟、高吞吐的优秀性能,并且非常擅长处理有状态的复杂计算逻辑场景2.简述Flink的核心概念?Flink的核心概念主要有四个:EventStreams、State、Time和Snapsho......
  • 数据结构(队列)
    文章目录一、概念与结构二、队列的实现QueueNode.hQueue.c初始化判断队列为空队尾,入队列队头,出队列取队头数据取队尾数据取队列有效元素个数销毁队列test.c一、概念与结构......
  • [C++]优先级队列
    1.了解优先级队列优先级队列是一种容器适配器,根据一些严格的弱排序标准,专门设计使其第一个元素始终是它所包含的元素中最大的元素。此上下文类似于堆,其中可以随时插入元素,并且只能检索最大堆元素(优先级队列中顶部的元素)。优先级队列是作为容器适配器实现的,容器适配器是使......
  • 顺序表实现队列(c语言)
    队列概念篇图示代码篇1.队列的声明2.队列的创建3.队列的销毁4.队列扩容5.入列6.出列6.队首元素7.队列的元素个数完整代码运行结果建议你在看这篇文章先看一下顺序表知识。我在这里通过顺序表的写法实现先进先出的特征来实现队列。当然顺序表也可以实现栈,感......
  • 深入理解淘客返利系统中的异步消息处理与队列技术
    深入理解淘客返利系统中的异步消息处理与队列技术大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代的淘客返利系统中,高并发和复杂的业务需求要求我们采用异步消息处理和队列技术来提高系统的性能和可伸缩性。本文将深入探讨在淘客返利系统中如......
  • 使用Java和RabbitMQ构建消息队列系统
    使用Java和RabbitMQ构建消息队列系统大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨如何使用Java和RabbitMQ构建一个高效的消息队列系统。RabbitMQ是一个开源的消息中间件,支持多种消息协议,能够帮助我们实现异步处理和解耦。1.Rabbit......
  • 【专题】2024年中国AIGC行业应用价值研究报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=36570原文出处:拓端数据部落公众号大模型的发展标志着AIGC时代的来临,没有大模型支撑的AI已成为旧时代产物,缺乏竞争力。技术的突破始终是AI发展的关键,而商业应用则是推动其迅速发展的加速器。AI的持久繁荣依赖于其商业化的成功。展望2024年,我们有......
  • 基于Python语言的入门算法和数据结构(持续更新中,求关注一波)[链表 栈 队列 复杂度 操作]
    这篇文章主要是讲的Python语言的算法,本人还在不断记笔记中,文章也会持续更新,内容比较浅薄,请大家指教另外推荐一个比较好用的记笔记的软件Typora,自己已经使用很久了,感觉不错。。。虽然但是还是有欠缺。目录第一章算法概述1.1什么是数据结构?01数据结构都有哪些组成方式02......
  • RabbitMQ-最常用的消息队列MQ安装详解!!
    RabbitMQ-最常用的消息队列MQ安装详解!!RabbitMQ-简介RabbitMQ是采用Erlang语言实现的高级消息队列协议(AMQP)的消息中间件。它最初起源于金融系统,用于在分布式系统中存储和转发消息。在RabbitMQ中,消息传递的过程可以想象成厨师做好饭菜放到服务台,服务台会暂存并最终将......
  • 使用Java实现高性能的消息队列系统在淘客返利系统中的应用
    使用Java实现高性能的消息队列系统在淘客返利系统中的应用大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!消息队列系统是一种重要的组件,用于实现系统之间的异步通信和解耦。在淘客返利系统中,通过使用高性能的Java消息队列系统,可以提高系统的稳定性......