栈就像叠猫猫,遵循"先入后出"的原则;队列就像猫猫排队,遵循”先入先出“的原则。栈和队列均可以通过数组(顺序表)和链表(链表)来实现。

1.栈

栈的主要操作可以分为以下几种:

方法 描述 时间复杂度
push() 元素入栈(添加至栈顶) O(1)
pop() 栈顶元素出栈 O(1)
peek() 访问栈顶元素 O(1)

1.1基于数组实现栈

1.1.1定义栈的结构体

  1. typedef int ElemType;
  2. typedef struct {
  3. ElemType* data;
  4. int length;
  5. }SqStack;

1.1.2栈的初始化

  1. SqStack *InitStack() {
  2. SqStack* stack = malloc(sizeof(SqStack));
  3. stack->data = (ElemType*)malloc(sizeof(ElemType)*Max_Size);
  4. stack->length = 0;
  5. return stack;
  6. }

1.1.3栈的释放

  1. //栈的释放
  2. void DestoryStack(SqStack* stack) {
  3. free(stack->data);
  4. free(stack);
  5. }

1.1.4元素入栈

  1. void push(SqStack* stack,ElemType e) {
  2. if(stack->length == Max_Size) {
  3. printf("栈满!\n");
  4. return;
  5. }
  6. stack->data[stack->length++] = e;
  7. }

stack->data[stack->length++] = e;:如果栈未满,将元素 e 存储在栈的当前位置(由 stack->length 指示),然后增加 stack->length 的值,表示栈中元素的数量增加了。

1.1.5元素出栈

  1. //元素出栈
  2. ElemType pop(SqStack* stack) {
  3. if (stack->length == 0) {
  4. printf("栈空!\n");
  5. return -1;
  6. }
  7. return stack->data[stack->length--];
  8. }

1.1.6访问栈顶元素

  1. //访问栈顶元素
  2. ElemType peek(SqStack* stack) {
  3. if(stack->length == 0) {
  4. printf("栈空!\n");
  5. return -1;
  6. }
  7. return stack->data[stack->length-1];
  8. }

1.2基于链表实现栈

1.2.1链表的结构体定义

  1. typedef int ElemType;
  2. //定义链表结构体
  3. typedef struct StackNode{
  4. ElemType* data;
  5. struct StackNode* next;
  6. }StackNode, *LinkStackPtr;
  7. //定义栈的结构体
  8. typedef struct {
  9. StackNode* top;
  10. int length;
  11. }LinkStack;

1.2.2初始化栈

  1. //初始化栈
  2. LinkStack* InitStack() {
  3. LinkStack* s = malloc(sizeof(LinkStack));
  4. if (s == NULL) {
  5. printf("内存分配失败!\n");
  6. return NULL;
  7. }
  8. s->top = NULL;
  9. s->length = 0;
  10. return s;
  11. }

1.2.3销毁栈

  1. //销毁栈
  2. void DestroyStack(LinkStack* s) {
  3. //由栈顶到栈底,逐次释放
  4. while (s->top) {
  5. StackNode *n = s->top;
  6. free(n);
  7. s->top = s->top->next;
  8. }
  9. free(s);
  10. }

1.2.4元素出栈

  1. //元素出栈
  2. ElemType pop(LinkStack* s) {
  3. StackNode *node = malloc(sizeof(StackNode));
  4. node->data = s->top->data;//将元素复制到node链表
  5. StackNode *tmp = s->top;
  6. s->top = s->top->next;//这里将top更新
  7. free(tmp);
  8. s->length--;
  9. return node->data;
  10. }

1.2.5访问栈顶元素

  1. //访问栈顶元素
  2. ElemType peek(LinkStack* s) {
  3. if(s->length == 0) {
  4. printf("栈空");
  5. return -1;
  6. }
  7. return s->top->data;
  8. }

2.队列

为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素,链表和数组都符合要求。

2.1基于数组的队列

2.1.1队列的结构体定义

  1. //结构体定义
  2. typedef int ElemType;
  3. typedef struct {
  4. ElemType* data;
  5. ElemType front; //队首指针
  6. ElemType end; //队尾指针
  7. int length; //队列长度
  8. }ArrayQueue;

2.1.2队列的初始化

  1. //队列的初始化
  2. ArrayQueue *InitQueue(int queCapcity) {
  3. ArrayQueue* queue = (ArrayQueue*)malloc(sizeof(ArrayQueue));
  4. queue->length = queCapcity;
  5. queue->front = queue->end = 0;
  6. queue->data = (ElemType*)malloc(sizeof(ElemType)*queue->length);
  7. return queue;
  8. }

2.1.3销毁队列

  1. //销毁队列
  2. bool DestoryQueue(ArrayQueue* queue) {
  3. free(queue->data);
  4. free(queue);
  5. return true;
  6. }

2.1.4入队

  1. //入队
  2. void push(ArrayQueue* queue,ElemType e) {
  3. if(queue->length == queue->end) {
  4. printf("队满");
  5. return;
  6. }
  7. int rear = (queue->front + queue->end) % queue->length;
  8. queue->data[rear] = e;
  9. queue->end++;
  10. }

2.1.5访问队首元素

  1. //访问队首元素
  2. ElemType geek(ArrayQueue* queue) {
  3. return queue->data[queue->front];
  4. }

2.1.6出队

  1. //出队
  2. ElemType pop(ArrayQueue* queue) {
  3. ElemType num = peek(queue);
  4. queue->front = (queue->front + 1) % queue->length;
  5. return num;
  6. }

2.2基于链表的队列

2.1.1队列结构体的定义

我们可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。

  1. typedef int ElumType;
  2. typedef struct Linklist{
  3. ElumType* data;
  4. struct Linklist* next;
  5. }LNode;
  6. typedef struct {
  7. LNode *front,*rear;
  8. int quelength;
  9. }LinkListQueue;

2.1.2队列初始化

  1. //队列的初始化
  2. LinkListQueue* InitLinkListQueue() {
  3. LinkListQueue* queue = (LinkListQueue*)malloc(sizeof(LinkListQueue));
  4. queue->front = NULL;
  5. queue->rear = NULL;
  6. queue->quelength = 0;
  7. return queue;
  8. }

2.1.3队列的删除

  1. //队列的删除
  2. void DestroyLinkListQueue(LinkListQueue *queue) {
  3. while (queue->front != NULL) {
  4. LNode* temp = queue->front;
  5. queue->front = queue->front->next;
  6. free(temp);
  7. }
  8. free(queue);
  9. }

2.1.4元素入队

  1. //入队
  2. bool push(LinkListQueue* queue,ElumType e) {
  3. LNode* node = (LNode*)malloc(sizeof(LNode));
  4. node->data = e;
  5. //队列为空,头尾指针都指向node
  6. if(queue->quelength == 0) {
  7. queue->front = node;
  8. queue->rear = node;
  9. queue->quelength++;
  10. }
  11. else {
  12. queue->rear->next = node;
  13. queue->rear = node;
  14. queue->quelength++;
  15. }
  16. return true;
  17. }

2.1.5访问队首元素

  1. //访问队首元素
  2. ElumType peek(LinkListQueue* queue) {
  3. if(queue->quelength == 0) {
  4. printf("队空!\n");
  5. return -1;
  6. }
  7. return queue->front->data;
  8. }

2.1.6出队

  1. //出队
  2. ElumType pop(LinkListQueue* queue) {
  3. ElumType num = peek(queue);
  4. LNode *tmp = queue->front;
  5. queue->front = queue->front->next;
  6. free(tmp);
  7. queue->quelength--;
  8. return num;
  9. }

以上是栈与队列的一些基本操作,原版代码上传至(https://gitee.com/shi-chengfu)

如果有错误请联系QQ:303613518

栈与队列(c语言实现)的更多相关文章

  1. 4-29 c语言之栈,队列,双向链表

    今天学习了数据结构中栈,队列的知识 相对于单链表来说,栈和队列就是添加的方式不同,队列就相当于排队,先排队的先出来(FIFO),而栈就相当于弹夹,先压进去的子弹后出来(FILO). 首先看一下栈(St ...

  2. <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现

    栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...

  3. C语言数据结构——第三章 栈和队列

    三.栈和队列 栈和队列是两种重要的线性结构.从数据结构的角度来看,栈和队列也是线性表,它的特殊性在于栈和队列的基本操作是线性表操作的子集,它们的操作相对于线性表来说是受到限制的,因此,可以称其为限定性 ...

  4. 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

    表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...

  5. C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...

  6. 数据结构(C语言版)-第3章 栈和队列

    3.1 栈和队列的定义和特点3.2 案例引入3.3 栈的表示和操作的实现3.4 栈与递归3.5 队列的的表示和操作的实现3.6 案例分析与实现 基本操作有入栈.出栈.读栈顶元素值.建栈.判断栈满.栈空 ...

  7. C++学习(三十)(C语言部分)之 栈和队列

    数据结构1.保存数据 2.处理数据数组+操作增查删改 栈和队列是一种操作受限的线性表 栈 是先进后出 是在一端进行插入删除的操作--->栈顶 另一端叫做栈底(栈和栈区是两个概念)(是一种数据结构 ...

  8. 栈和队列ADT -数据结构(C语言实现)

    数据结构与算法分析 栈模型 限制插入和删除只能在表的末端的表 表的末端叫做栈顶(top) 支持Push进栈和Pop入栈操作 //LIFO后进先出表 栈的实现 链表实现 类型声明 struct Node ...

  9. 数据结构(c语言版,严蔚敏)第3章栈和队列

    第3章栈和队列

  10. LeetCode 232题用栈实现队列(Implement Queue using Stacks) Java语言求解

    题目链接 https://leetcode-cn.com/problems/implement-queue-using-stacks/ 题目描述 使用栈实现队列的下列操作: push(x) -- 将一 ...

随机推荐

  1. JAVA集合专题之深入学习

    1.背景 集合虽然用起来非常简单... 但是面试确问得很多,很深.... 最重要的是集合的设计里面使用了大量的非常典型的多线程设计... 如果能把集合中的源码学一遍,相信你的多线程功底会大大提升... ...

  2. JavaScript设计模式样例七 —— 原型模式

    原型模式(Prototype Pattern) 定义:用于创建重复的对象,同时又能保证性能.目的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.场景:在运行期建立和删除原型. let ...

  3. Figma 替代品 Penpot 安装和使用教程

    在设计领域,Figma 无疑是一个巨人.它彻底改变了设计流程,将协作带到了一个全新的高度.然而,随着 Adobe 收购 Figma 的消息传出,许多设计师和开发者开始担心:Figma 未来会如何演变? ...

  4. 技术如何通过API接口获取自己想要同款商品的数据

    确定数据源: 首先,你需要确定哪些平台或服务提供商提供了你感兴趣的商品数据.例如,电商平台.品牌商.市场调研公司等. 了解API文档: 访问提供商的开发者门户网站,阅读API文档.文档会详细介绍如何使 ...

  5. IE中在线预览PDF文件

    今天在项目中偶然遇到一个需要在线查看pdf的需求.在查阅一些资料之后使用了最简单的写法(需要在客户端安装AdbeRdr11000_zh_CN_11.0.0.379.exe软件). 还有其他方法可以实现 ...

  6. Python新手爬虫二:爬取搜狗图片(动态)

    经过上一期爬取豆瓣影评成功后,感觉爬虫还不错,于是想爬点图片来玩玩... 搜狗图片地址:https://pic.sogou.com/?from=category 先上最后成功的源码(在D盘下创建sou ...

  7. .Net 5.0 WebAPI 发布至 CentOS 7 系统

    〇.前言 本文主要介绍了在 CentOS 7 上部署 WebAPI 项目的过程. 先安装 .net 5.0 的环境,再创建一个示例项目并发布至 CentOS 上,同时列明了一些注意的点:最后将 dot ...

  8. .NET 8 微软免费开源的 Blazor UI 组件库

    前言 .NET 8 的发布,微软推出了官方免费且开源的 Blazor UI 组件库 -- Fluent UI Blazor. 组件库提供了Web应用程序所需的工具,确保应用程序能够与 Microsof ...

  9. 原生JavaScript实现可旋转立方体效果基础示例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 探索AI人才培养新范式,合合信息与同济大学软件学院签署产教融合人才培养协议

    随着科学技术的发展,促进人工智能产业与高校人才培养相融合,正成为业界关注的焦点.7月3日,上海合合信息科技股份有限公司(以下简称:合合信息)与同济大学软件学院"产教融合人才培养签约暨创新实践 ...