栈与队列(c语言实现)
栈就像叠猫猫,遵循"先入后出"的原则;队列就像猫猫排队,遵循”先入先出“的原则。栈和队列均可以通过数组(顺序表)和链表(链表)来实现。
1.栈
栈的主要操作可以分为以下几种:
| 方法 | 描述 | 时间复杂度 |
|---|---|---|
| push() | 元素入栈(添加至栈顶) | O(1) |
| pop() | 栈顶元素出栈 | O(1) |
| peek() | 访问栈顶元素 | O(1) |
1.1基于数组实现栈
1.1.1定义栈的结构体
typedef int ElemType;
typedef struct {
ElemType* data;
int length;
}SqStack;
1.1.2栈的初始化
SqStack *InitStack() {
SqStack* stack = malloc(sizeof(SqStack));
stack->data = (ElemType*)malloc(sizeof(ElemType)*Max_Size);
stack->length = 0;
return stack;
}
1.1.3栈的释放
//栈的释放
void DestoryStack(SqStack* stack) {
free(stack->data);
free(stack);
}
1.1.4元素入栈
void push(SqStack* stack,ElemType e) {
if(stack->length == Max_Size) {
printf("栈满!\n");
return;
}
stack->data[stack->length++] = e;
}
stack->data[stack->length++] = e;:如果栈未满,将元素e存储在栈的当前位置(由stack->length指示),然后增加stack->length的值,表示栈中元素的数量增加了。
1.1.5元素出栈
//元素出栈
ElemType pop(SqStack* stack) {
if (stack->length == 0) {
printf("栈空!\n");
return -1;
}
return stack->data[stack->length--];
}
1.1.6访问栈顶元素
//访问栈顶元素
ElemType peek(SqStack* stack) {
if(stack->length == 0) {
printf("栈空!\n");
return -1;
}
return stack->data[stack->length-1];
}
1.2基于链表实现栈
1.2.1链表的结构体定义
typedef int ElemType;
//定义链表结构体
typedef struct StackNode{
ElemType* data;
struct StackNode* next;
}StackNode, *LinkStackPtr;
//定义栈的结构体
typedef struct {
StackNode* top;
int length;
}LinkStack;
1.2.2初始化栈
//初始化栈
LinkStack* InitStack() {
LinkStack* s = malloc(sizeof(LinkStack));
if (s == NULL) {
printf("内存分配失败!\n");
return NULL;
}
s->top = NULL;
s->length = 0;
return s;
}
1.2.3销毁栈
//销毁栈
void DestroyStack(LinkStack* s) {
//由栈顶到栈底,逐次释放
while (s->top) {
StackNode *n = s->top;
free(n);
s->top = s->top->next;
}
free(s);
}
1.2.4元素出栈
//元素出栈
ElemType pop(LinkStack* s) {
StackNode *node = malloc(sizeof(StackNode));
node->data = s->top->data;//将元素复制到node链表
StackNode *tmp = s->top;
s->top = s->top->next;//这里将top更新
free(tmp);
s->length--;
return node->data;
}
1.2.5访问栈顶元素
//访问栈顶元素
ElemType peek(LinkStack* s) {
if(s->length == 0) {
printf("栈空");
return -1;
}
return s->top->data;
}
2.队列
为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素,链表和数组都符合要求。
2.1基于数组的队列
2.1.1队列的结构体定义
//结构体定义
typedef int ElemType;
typedef struct {
ElemType* data;
ElemType front; //队首指针
ElemType end; //队尾指针
int length; //队列长度
}ArrayQueue;
2.1.2队列的初始化
//队列的初始化
ArrayQueue *InitQueue(int queCapcity) {
ArrayQueue* queue = (ArrayQueue*)malloc(sizeof(ArrayQueue));
queue->length = queCapcity;
queue->front = queue->end = 0;
queue->data = (ElemType*)malloc(sizeof(ElemType)*queue->length);
return queue;
}
2.1.3销毁队列
//销毁队列
bool DestoryQueue(ArrayQueue* queue) {
free(queue->data);
free(queue);
return true;
}
2.1.4入队
//入队
void push(ArrayQueue* queue,ElemType e) {
if(queue->length == queue->end) {
printf("队满");
return;
}
int rear = (queue->front + queue->end) % queue->length;
queue->data[rear] = e;
queue->end++;
}
2.1.5访问队首元素
//访问队首元素
ElemType geek(ArrayQueue* queue) {
return queue->data[queue->front];
}
2.1.6出队
//出队
ElemType pop(ArrayQueue* queue) {
ElemType num = peek(queue);
queue->front = (queue->front + 1) % queue->length;
return num;
}
2.2基于链表的队列
2.1.1队列结构体的定义
我们可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。
typedef int ElumType;
typedef struct Linklist{
ElumType* data;
struct Linklist* next;
}LNode;
typedef struct {
LNode *front,*rear;
int quelength;
}LinkListQueue;
2.1.2队列初始化
//队列的初始化
LinkListQueue* InitLinkListQueue() {
LinkListQueue* queue = (LinkListQueue*)malloc(sizeof(LinkListQueue));
queue->front = NULL;
queue->rear = NULL;
queue->quelength = 0;
return queue;
}
2.1.3队列的删除
//队列的删除
void DestroyLinkListQueue(LinkListQueue *queue) {
while (queue->front != NULL) {
LNode* temp = queue->front;
queue->front = queue->front->next;
free(temp);
}
free(queue);
}
2.1.4元素入队
//入队
bool push(LinkListQueue* queue,ElumType e) {
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = e;
//队列为空,头尾指针都指向node
if(queue->quelength == 0) {
queue->front = node;
queue->rear = node;
queue->quelength++;
}
else {
queue->rear->next = node;
queue->rear = node;
queue->quelength++;
}
return true;
}
2.1.5访问队首元素
//访问队首元素
ElumType peek(LinkListQueue* queue) {
if(queue->quelength == 0) {
printf("队空!\n");
return -1;
}
return queue->front->data;
}
2.1.6出队
//出队
ElumType pop(LinkListQueue* queue) {
ElumType num = peek(queue);
LNode *tmp = queue->front;
queue->front = queue->front->next;
free(tmp);
queue->quelength--;
return num;
}
以上是栈与队列的一些基本操作,原版代码上传至(https://gitee.com/shi-chengfu)
如果有错误请联系QQ:303613518
栈与队列(c语言实现)的更多相关文章
- 4-29 c语言之栈,队列,双向链表
今天学习了数据结构中栈,队列的知识 相对于单链表来说,栈和队列就是添加的方式不同,队列就相当于排队,先排队的先出来(FIFO),而栈就相当于弹夹,先压进去的子弹后出来(FILO). 首先看一下栈(St ...
- <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现
栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...
- C语言数据结构——第三章 栈和队列
三.栈和队列 栈和队列是两种重要的线性结构.从数据结构的角度来看,栈和队列也是线性表,它的特殊性在于栈和队列的基本操作是线性表操作的子集,它们的操作相对于线性表来说是受到限制的,因此,可以称其为限定性 ...
- 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes
表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...
- C语言数据结构基础学习笔记——栈和队列
之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...
- 数据结构(C语言版)-第3章 栈和队列
3.1 栈和队列的定义和特点3.2 案例引入3.3 栈的表示和操作的实现3.4 栈与递归3.5 队列的的表示和操作的实现3.6 案例分析与实现 基本操作有入栈.出栈.读栈顶元素值.建栈.判断栈满.栈空 ...
- C++学习(三十)(C语言部分)之 栈和队列
数据结构1.保存数据 2.处理数据数组+操作增查删改 栈和队列是一种操作受限的线性表 栈 是先进后出 是在一端进行插入删除的操作--->栈顶 另一端叫做栈底(栈和栈区是两个概念)(是一种数据结构 ...
- 栈和队列ADT -数据结构(C语言实现)
数据结构与算法分析 栈模型 限制插入和删除只能在表的末端的表 表的末端叫做栈顶(top) 支持Push进栈和Pop入栈操作 //LIFO后进先出表 栈的实现 链表实现 类型声明 struct Node ...
- 数据结构(c语言版,严蔚敏)第3章栈和队列
第3章栈和队列
- LeetCode 232题用栈实现队列(Implement Queue using Stacks) Java语言求解
题目链接 https://leetcode-cn.com/problems/implement-queue-using-stacks/ 题目描述 使用栈实现队列的下列操作: push(x) -- 将一 ...
随机推荐
- maven实战教程-含视频讲解
1.背景 2.什么是maven? 通俗的说就是,不用手动拷贝jar包,帮我们管理项目结构,只需要配置坐标,自动从中央仓库下载(其他介绍请百度...). 3.Maven的安装与配置 注意:Maven在使 ...
- css 样式 element.style 覆盖问题
问题: 我们在写网页定制样式的时候发现展示效果跟我们预想的不一样? 打开F12一看原来是element.style 覆盖的我定义的效果. 解决: 只要在定义的内容后面加上 !important 就行啦 ...
- 京东面试:说说CMS工作原理?
CMS(Concurrent Mark Sweep)垃圾收集器是以"最短的停顿"著称的垃圾回收器,因此也是 JDK 9 之前使用最广泛的垃圾回收器之一.那么,问题来了,为什么 CM ...
- SMU Summer 2023 Contest Round 2
SMU Summer 2023 Contest Round 2 A. Treasure Hunt 当\(x1 - x2\)的差值与\(y1-y2\)的差值都能被\(x,y\)整除时,且商之和为2的倍数 ...
- RISC-V全志D1多媒体套件文章汇总
提示 此开发板的任何问题都可以在我们的论坛交流讨论 https://forums.100ask.net/c/aw/d1/57 文章目录汇总 教程共计14章,下面是章节汇总: 第0章_RISC-V全志D ...
- 抖音集团 FlinkSQL 性能优化探索及实践
本文作者:李精卫 更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 背景 随着抖音集团内部对流式任务的需求不断增长,Flink SQL作为一种低成本接入手段 ...
- Vite+Vue3 项目 华仔待办
此"华仔",不是彼"华仔",你懂的! 先来了个截图 紧跟着,实现步骤也来了 1. 安装 Node.js,终端运行 npm create vue@latest,项 ...
- uni-app 路由封装(简易版)
在实践运用中,经常需要在路由跳转时判断是否需要登录权限,页面跳转时,添加加在if判断. 插件市场也有一些这种插件,配置也稍微复制,大部分朝向vue-router. 注:本次路由封装,只是单纯的判断是否 ...
- Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板
基于electron32+vue3 setup+pinia2桌面端os管理解决方案ElectronVue3OS. vue3-electron32-os全新原创Electron32+Vite5+Vue3 ...
- C# 泛型对象和DataTable之间的相互转换
应用场景 实际开发场景下会经常出现DataTable和List对象需要相互转换的时候,通过方法提取避免重复造轮子 List转换成DataTable 基本思路: 向DataTable里面添加新的数据内容 ...