数据结构--栈与队列【您的关注是我创作的动力!】

ops/2024/11/8 22:41:19/

文章目录

    • 什么是栈?
    • 栈的具体实现
  • 队列
    • 什么是队列?
    • 队列的实现


什么是栈?

栈也是顺序表的一种,栈的逻辑实现是先进后出(后进先出)就跟子弹夹一样。
具体逻辑就是它只允许在固定的一端进行数据的插入与删除,在数据插入与删除的一端称为
栈顶,另一端称为栈低
压栈:插入数据的名称,在栈顶插入数据
出栈:删除数据的名称,   在栈顶删除数据

如图:
在这里插入图片描述

栈的具体实现

我们可以用双链表,单链表,数组来实现栈,
本文采用数组来实现栈,因为双链表的指针太多,浪费,单链表每次创建节点都需要去用操作系统
也是比较浪费资源。

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h> //用于引用动态内存函数
#include<stdbool.h>//用于使用布尔类型
#include<assert.h>
typedef int Datatype;
typedef struct Stack {Datatype* arr;   //定义数组来实现栈。那么进栈与出栈的操作用尾插与尾删实现int capacity;   //已经申请的空间int top;       //用top的数值代表栈顶指针,指向第几个元素
}ST;
//栈的初始化
void StackInitialize(ST* p);
//判断空间是否足够,不够则扩容
void Deter(ST* p);
//进栈
void StackInsert(ST* p, Datatype x);
//出栈
void StackDelete(ST* p);
//返回栈顶的元素
Datatype StackTop(ST* p);
//求栈中元素的个数
int StackSize(ST* p);
//判断栈是否为空
bool StackEmpty(ST* p);
//栈的销毁
void StackDestory(ST* p);

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//栈的初始化
void StackInitialize(ST*p) {//将栈的空间初始置为4个元素的大小p->arr = (Datatype *)malloc(4 * sizeof(Datatype));//栈的初始元素个数为0p->top = 0; //top的初始值为0代表,表示栈顶指针指向栈顶元素的下一个元素//这个栈顶指针的理解可以从p->size元素个数的角度理解//p-size-1就相当于栈顶指针指向的元素位置,p->size即元素的总个数//因为top代表栈顶指针指向栈顶的下一个元素,所以可以使用top-1来表示栈顶元素// 但是top为0时,则代表栈中没有元素,top-1也不能使用!                        p->capacity = 4;//初始化的空间为4个数据类型大小的空间
}
//判断空间是否足够,不够则扩容
void Deter(ST* p) {//判断空间是否足够,要看元素个数与空间个数是否相同//如果相同,则空间不足assert(p);if (p->top == p->capacity) {Datatype* p1 = realloc(p->arr, 2 * p->capacity * sizeof(Datatype));//如果扩展空间失败if (p1 == NULL) {printf("扩展空间失败\n");}//如果扩展空间成功,else {p->arr = p1;p->capacity = 2 * p->capacity;//记录增长二倍}}
}
//进栈
void StackInsert(ST*p,Datatype x) {assert(p);//先判断空间是否足够,如果不足,则扩容Deter(p);//从数组的尾部插入数据实现进栈p->arr[p->top++] = x;}
//出栈
void StackDelete(ST*p) {assert(p);//如果栈已经为空,还删除栈中内容则报错!assert(p->top > 0);p->top--;
}
//返回栈顶的元素
Datatype StackTop(ST *p) {assert(p);assert(p->top > 0);//栈不能为空,否则报错return p->arr[p->top - 1];
}
//求栈中元素的个数
int StackSize(ST*p) {assert(p);return p->top;
}
//判断栈是否为空
bool StackEmpty(ST*p) {assert(p);//查询栈中元素的个数即可if (p->top == 0) {//false表示为空return false;}else {return true;}
}
//栈的销毁
void StackDestory(ST *p) {assert(p);//栈的销毁需要先释放掉申请的空间free(p->arr);p->arr = NULL;p->top = p->capacity = 0;
}

队列

什么是队列?

队列也是线性表的一种,它的规则是只能在队列的一端插入数据,在另一端删除数   据,简称为:先进先出
出队列:进入数据删除的一端称为队头
入队列:进行数据插入的一端称为队尾

在这里插入图片描述

队列的实现

队列可以由数组,单链表,与双链表实现,
数组实现时,如果删除数据后,还需再挪动整个队列中的数据移动
双链表的指针太多,
所以我采用单链表:
进行尾插与头删
在这里插入图片描述

#pragma once  //用于避免头文件被重复引用
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义存储的数据类型
typedef int Datatype; //用单链表来实现队列
typedef struct QueueNode {Datatype data;struct QueueNode* Next;
}QN;
//初始化队列:
//因为要改变头指针,所以需要用二级指针
void QueueInitialize(QN** pphead);
//队尾入
//采用尾插法来实现
void QueueInsert(QN* phead, Datatype x);
//队头出
//出队列的实现用头删法
//因为头指针需要改变,所以用二级指针作为形参
void QueueDelete(QN** pphead);
//获取队头的数据
Datatype QueueFront(QN* phead);
//获取队尾的数据
Datatype QueueTail(QN* phead);
//获取队列中元素的个数
int QueueSize(QN* phead);
//判断队列是否为空
bool QueueEmpty(QN* phead);
//销毁队列
void QueueDestory(QN** phead);

在这里插入图片描述

#include"Queue.h"
//初始化队列:
//因为要改变头指针,所以需要用二级指针
void QueueInitialize(QN**pphead) {*pphead = NULL;
}
//队尾入
//采用尾插法来实现
void QueueInsert(QN*phead,Datatype x) {//先找到队尾QN* temp = phead;while (temp!= NULL) {temp = temp->Next;}temp = (QN*) malloc (sizeof(QN)); //创建一个新节点temp->data = x; //赋值temp->Next = NULL;}
//队头出
//出队列的实现用头删法
//因为头指针需要改变,所以用二级指针作为形参
void QueueDelete(QN**pphead) {//头删时,首节点不能为空assert(*pphead&&pphead);QN* tem = *pphead;*pphead = (*pphead)->Next;//将头指针指向第二个节点free(tem); //释放掉tem中指针指向的空间
}
//获取队头的数据
Datatype QueueFront(QN *phead) {assert(phead); //phead不能为空。return phead->data;
}
//获取队尾的数据
Datatype QueueTail(QN* phead) {assert(phead);QN* tem = phead;while (tem->Next!=NULL) {tem = tem->Next;}//找到尾节点后return tem->data;
}
//获取队列中元素的个数
int QueueSize(QN*phead) {int size = 0;QN* tem = phead;while (tem != NULL) {tem = tem->Next;size++;}return size;
}
//判断队列是否为空
bool QueueEmpty(QN*phead) {//如果队列为空,返回trueif (phead == NULL)return true;//如果队列不为空,返回falseelsereturn false;
}
//销毁队列
void QueueDestory(QN **phead) {assert(*phead&&phead);//销毁队列从头节点开始释放QN* tem = *phead;//当前节点不为空,就一直执行while (tem != NULL) {//先将现在节点的下一个节点地址放在cur变量中QN* cur = tem->Next;free(tem);tem = cur;}*phead = NULL;
}

http://www.ppmy.cn/ops/24765.html

相关文章

[1688]jsp工资投放管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 工资投放管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

LeetCode in Python 10. Regular Expression Matching (正则表达式匹配)

正则表达式匹配涉及到两个字符串的匹配问题&#xff0c;类似于寻找最大公共子串&#xff0c;可使用动态规划思想解决。重点和难点在于如何构建正确的状态转移方程。 示例&#xff1a; 图1 正则表达式匹配输入输出 代码&#xff1a; class Solution:def isMatch(self, s: st…

K8s初次入门

初步:搭建k8s集群 k8s 集群主机清单 主机名ip地址master1.50node-00011.51node-00021.52node-00031.53node-00041.54node-00051.55harbor1.30事先准备 所有的k8s集群主机卸载防火墙和禁用swap交换空间(docker、k8s建议禁用swap) 安装工具 dnf install -y kubeadm kubelet ku…

【算法每日一练】

蛮有意思的的一道题&#xff0c;最后要判断能否成为一种1~n的全排列&#xff0c;我最这样做的&#xff1a; 整个数组先排序一下。假设遍历到了i&#xff0c;那就判断前面b和r的个数&#xff0c;但是有想到了后面可能还会对前面的结果产生影响&#xff0c;所以就抛弃了这个想法…

某音a_bogus导出jsvmp加密函数到全局

记得加入我们的学习群&#xff1a;961566389 点击链接加入群聊&#xff1a;https://h5.qun.qq.com/s/62P0xwrCNO 上一篇文章我们说到s函数不是那么容易导出&#xff0c;但是后面分析&#xff0c;发现虽然他们都叫e函数&#xff0c;但是&#xff0c;每个e函数下面的_v里面的数…

FSNotes for Mac v6.7.1中文激活版:强大的笔记管理工具

FSNotes for Mac是一款功能强大的文本处理与笔记管理工具&#xff0c;为Mac用户提供了一个直观、高效的笔记记录和整理平台。 FSNotes for Mac v6.7.1中文激活版下载 FSNotes支持Markdown语法&#xff0c;使用户能够轻松设置笔记格式并添加链接、图像等元素&#xff0c;实现笔记…

Web3的可持续性:构建环境友好的去中心化系统

引言 随着全球对可持续发展和环境问题的日益关注&#xff0c;Web3技术作为一种新型的互联网模式&#xff0c;也开始受到社区和开发者的关注。但很少有人关注到Web3对环境可持续性的潜在影响。本文将探讨Web3如何构建一个环境友好的去中心化系统&#xff0c;以及这如何促进一个…

2024年CMS市场的份额趋势和使用统计

目前市面上有超过一半的网站都是使用CMS来搭建的&#xff0c;据不完全统计&#xff0c;现在大概有900多种CDM可供选择&#xff0c;以下是最常见的CMS的市场份额和使用率信息&#xff1a; 除了WordPress以外&#xff0c;Shopify和Wix也是比较流行的内容管理系统&#xff0c;尤其…