数据结构|栈和队列以及实现

栈和队列

  • 一、栈
    • 1.1栈的概念及结构
    • 1.2栈的实现
  • 二、队列
    • 2.1队列的概念及结构
    • 2.2队列的实现

一、栈

1.1栈的概念及结构

  • 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和数据删除的一端称为栈顶,另一端称为栈顶。 栈中的数据元素遵循后进先出的原则,简称LIFO(Last In First Out)。
  • 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
  • 出栈:栈的删除操作叫做出栈。出数据也在栈顶。

示意图:
在这里插入图片描述
在这里插入图片描述

1.2栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
两者实现的连续区别:数组栈在空间上是连续的,而链表栈在空间上是不连续的,在逻辑上是连续的。当然不管栈用什么实现,基本上都离不开结构体

区别示意图:
数组栈:
在这里插入图片描述
链栈:
在这里插入图片描述

数组栈的增删查改实现,还是分为三大模块,stack.h用来包含头文件及一些给用户看的数据、stack.c程序员用来实现函数的具体内容、test.c测试数组栈

//stack.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>//此为静态栈的结构,实际中一般不实用
//typedef int STDataType;
//typedef struct Stack
//{
//	STDataType a[N];
//	int top;
//}Stack;//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{STDataType *a;int top; //用来表示栈顶int capacity;//用来表示容量
}Stack;//初始化栈
void StackInit(Stack* ps);//入栈
void StackPush(Stack* ps, STDataType data);//出栈
void StackPop(Stack* ps);//获取栈顶元素
STDataType StackTop(Stack* ps);//获取栈中有效元素个数
int StackSize(Stack* ps);//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps);//销毁栈
void StackDestroy(Stack* ps);
//stack.c
#include "Stack.h"//初始化栈
void StackInit(Stack* ps)
{ps->a = NULL;ps->top = 0;ps->capacity = 0;
}//入栈
void StackPush(Stack* ps, STDataType data)
{assert(ps);if (ps->top == ps->capacity){ps->capacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;}ps->a[ps->top] = data;ps->top++;
}//出栈
void StackPop(Stack* ps)
{assert(ps->top > 0);ps->top--;
}//获取栈顶元素
STDataType StackTop(Stack* ps)
{assert(ps->top > 0);return ps->a[ps->top-1];
}//获取栈中有效元素个数
int StackSize(Stack* ps)
{assert(ps);return ps->top;
}//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps)
{assert(ps);return ps->top == 0;
}//销毁栈
void StackDestroy(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}
//test.c
//这里是一些测试数据
#include "Stack.h"
#include "Queue.h"void Stacktest()
{Stack s;Stack* st = &s;StackInit(st);StackPush(st, 1);StackPush(st, 2);StackPush(st, 3);StackPush(st, 4);StackPush(st, 5);while (!StackEmpty(st)){printf("%d->", StackTop(st));StackPop(st);}printf("\n");StackDestroy(st);
}
int main()
{Stacktest();return 0;
}

测试结果:
在这里插入图片描述

二、队列

2.1队列的概念及结构

队列:只允许一端进行插入数据操作,在另一端进行删除数据操作的特殊性线性表,队列具有先进先出FIFO(First In First Out)入队列:进行插入操作的一端称为队尾出队列:进行删除操作的一端成为队头

示意图:
在这里插入图片描述

2.2队列的实现

队列当然也可以用数组和链表的结构实现,使用链栈的结构实现要更优一些,因为链式结构在出队列的时候的效率要比数组高,链式结构只要用两个指针可以控制队头队尾,而数组结构在出队头数据的时候无法确定头,需要更多的变量来记录头,效率大大降低

示意图:
在这里插入图片描述
在这里插入图片描述
以上为图的形象表示,接下来,我们进行代码来实现此结构,一样分为三个部分,Queue.h,Queue.c,test.c

//Queue.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QDataType;
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;//队列的结构
typedef struct Queue
{QNode* front;QNode* rear;
}Queue;//初始化队列
void QueueInit(Queue* q);//队尾入队列
void QueuePush(Queue* q, QDataType data);//对头出队列
void QueuePop(Queue* q);//获取队列头部元素
QDataType QueueFront(Queue* q);//获取队尾元素
QDataType QueueBack(Queue* q);//获取队列中有效元素个数
int QueueSize(Queue* q);//检测队列是否为空,如果为空返回真,如果非空返回假
bool QueueEmpty(Queue* q);//销毁队列
void QueueDestroy(Queue* q);
//Queue.c
#include "Queue.h"//初始化队列
void QueueInit(Queue* q)
{q->front = NULL;q->rear = NULL;
}//队尾入队列
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}if (q->front == NULL){q->rear = newnode;q->rear->data = data;q->front = q->rear;q->rear->next = NULL;}else{q->rear->next = newnode;q->rear = newnode;q->rear->data = data;q->rear->next = NULL;}}//队头出队列
void QueuePop(Queue* q)
{assert(q);assert(q->front);QNode* pnext = q->front->next;free(q->front);q->front = pnext;
}//获取队列头部元素
QDataType QueueFront(Queue* q)
{assert(q);assert(q->front);return q->front->data;
}//获取队尾元素
QDataType QueueBack(Queue* q)
{assert(q);assert(q->rear);return q->rear->data;
}//获取队列中有效元素个数
int QueueSize(Queue* q)
{assert(q);assert(q->front);QNode* num = q->front;int size = 0;while (num){size++;num = num->next;}return size;
}//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* q)
{assert(q);return q->front == NULL;
}//销毁队列
void QueueDestroy(Queue* q)
{assert(q);assert(q->front);while (q->front){QueuePop(q);}q->rear = NULL;
}
#include "Queue.h"void Queuetest()
{Queue queue;Queue* q = &queue;QueueInit(q);QueuePush(q, 1);QueuePush(q, 2);QueuePush(q, 3);QueuePush(q, 4);QueuePush(q, 5);while (!QueueEmpty(q)){printf("%d->", q->front->data);QueuePop(q);}
}int main()
{Queuetest();return 0;
}

测试结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/101186.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023 年高教社杯全国大学生数学建模竞赛题目 B 题 多波束测线问题

B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀速直线传播&#xff0c;在不同界面上产生反射&#xff0c;利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信号&#xff0c;并记录从声波发射到信号接收的传播…

【Linux】- 一文秒懂shell编程

shell编程 1.1 Shell 是什么1.2 Shell 脚本的执行方式1.3 编写第一个 Shell 脚本2.1 Shell 的变量2.2 shell 变量的定义2.3 设置环境变量3.1 位置参数变量3.2 预定义变量4.1 运算符4.2 条件判断5.1 流程控制5.2 case 语句5.3 for 循环5.4 while 循环5.5 read基本语法6.1函数6.2…

API安全学习 - crAPI漏洞靶场与API测试思路

crAPI漏洞靶场与解题思路 1. 前置基础1.1 认识crAPI1.2 环境搭建1.3 API的分类与鉴别 2. 漏洞验证2.1 失效的对象级别授权挑战1&#xff1a;访问其它用户车辆的详细信息挑战2&#xff1a;访问其它用户的机械报告 2.2 失效的用户身份验证挑战3&#xff1a;重置其它用户的密码 2.…

CSS流光按钮-圆形

主要思路 仅保留一条边框 border-radius 50%drop-shadow动画 animation keyframes 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, …

python基础爬虫反爬破解

文章目录 爬虫初识1. HTTP协议与WEB开发&#xff08;1&#xff09;简介&#xff08;2&#xff09;socket套接字&#xff08;3&#xff09;请求协议与响应协议 2. requests&反爬破解&#xff08;1&#xff09;UA反爬&#xff08;2&#xff09;referer反爬&#xff08;3&…

考完试家长怎么查看孩子成绩和等级?

考试结束了&#xff0c;孩子们的成绩和等级也出来了&#xff0c;对于家长来说&#xff0c;如何快速方便地查看孩子的成绩和等级呢&#xff1f;今天&#xff0c;我要向大家介绍一个非常实用的工具——易查分&#xff0c;让家长们便捷高效了解孩子的学习成果。 好消息&#xff01…

h5开发网站-使用jquery来实现二层嵌套的左侧列表,点击后显示右侧内容的效果

一、需求&#xff1a; 使用jquery来实现二层嵌套的左侧列表&#xff0c;点击后显示右侧内容的效果。 二、思路&#xff1a; 为一级列表项和二级子列表项分别添加了点击事件处理程序。当一级列表项被点击时&#xff0c;使用.slideToggle()方法展开或收起对应的二级子列表项。…

【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka

作者简介 前言 博主之前写过一个完整的MQ系列&#xff0c;包含RabbitMQ、RocketMQ、Kafka&#xff0c;从安装使用到底层机制、原理。专栏地址&#xff1a; https://blog.csdn.net/joker_zjn/category_12142400.html?spm1001.2014.3001.5482 本文是该系列的清单综述&#xf…

睿趣科技:现在开一家抖音小店到底能不能做起来

抖音&#xff0c;这个年轻人熟悉的短视频平台&#xff0c;如今已成为许多创业者的新天地。在这个平台上&#xff0c;各种各样的小店如雨后春笋般涌现&#xff0c;它们以创意的产品和精彩的内容吸引了大批年轻用户。然而&#xff0c;要在抖音上开一家小店并不是一帆风顺的事情&a…

【网络编程】深入了解UDP协议:快速数据传输的利器

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

mysql UUID 作为主键的问题

UUID 在MySQL中&#xff0c;可以使用UUID()函数来生成一个新的UUID值。该函数的返回值是一个字符串类型&#xff0c;表示一个32位的十六进制数字&#xff0c;其中包含4个连字符“-”&#xff0c;例如&#xff1a;“6ccd780c-baba-1026-9564-0040f4311e29”。 varchar(32) 32*4…

JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)

基于JavaSpringbootVue的在线教育系统(源码数据库18000字论文)096 一、系统介绍 本系统前后端分离 本系统分为管理员、用户两种角色(管理员角色权限可自行分配) 用户功能&#xff1a; 注册、登录、课程预告、在线课程观看、学习资料下载、学习文章预览、个人信息管理、消息…