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

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语言实现)的更多相关文章

  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. 微信支付APIV3私钥与证书配置

    1.加载商户私钥(privateKey:私钥字符串) 这个私钥是下载证书的的:apiclient_key.pem 2.转换下单时的证书 文档:https://github.com/wechatpay- ...

  2. 《最新出炉》系列小成篇-Python+Playwright自动化测试-67 - 模拟手机浏览器兼容性测试

    1.简介 在日常工作中,我们会遇到需要使用不同的硬件设备测试兼容性的问题,尤其是现在手机型号基本上是每个厂家每年发布一款新机型,而且手机的屏幕大小分辨率五花八门的,我们基本不可能全部机型都用真机测试一 ...

  3. double四舍五入保留两位小数的方法

    1,DecimalFormat DecimalFormat decimalFormat = new DecimalFormat(".00"); 意思就是规定保留几位小数 使用时 d ...

  4. programmers model

    Handler模式一直使用MSP,所以在handler模式下处理器会忽略SPSEL位:异常进入及返回机制会更新CONTROL寄存器. 在操作系统的环境中,推荐线程在Thread模式下运行使用PSP,内 ...

  5. 从海量信息中脱颖而出:Workflow智能分析解决方案,大语言模型为AI科技文章打造精准摘要评分体系(总篇章)

    从海量信息中脱颖而出:Workflow智能分析解决方案,大语言模型为AI科技文章打造精准摘要评分体系(总篇章) 1.简介 该项目整合了编程.AI.产品设计.商业科技及个人成长等多领域的精华内容,源自顶 ...

  6. C# 读取DBF文件到Datatable

    此种方式不依赖与任何驱动,第三方插件. 核心代码TDbfTable如下: using System; using System.Collections.Generic; using System.Te ...

  7. Unix、Linux、GNU 关系梳理

    之前写了一篇 MSYS2.MinGW 和 Cygwin 关系梳理的博客,但是要讲清它们几个的关系最好还是先了解一下操作系统的发展历程.遂补充了这篇博客. UNIX:现代操作系统的始祖 Operatin ...

  8. 深入浅出Stream流

    Java 8的新特性之一就是流stream,配合同版本出现的 Lambda ,使得操作集合(Collection)提供了极大的便利. 案例引入 在JAVA中,涉及到对数组.Collection等集合类 ...

  9. 【YashanDB知识库】应用绑定参数的慢查询,慢日志抓取不到

    [问题分类]功能使用 [关键字]慢日志.绑定参数 [问题描述]应用下发的绑定参数的SQL,慢日志功能抓取不到查询耗时超过阈值的执行SQL [问题原因分析]慢日志的功能没有考虑绑定参数的情况 [解决/规 ...

  10. Graph 学习

    Graph basic terms 里面介绍了常见的一些基本概念,如 directed/undirected, weighted, cyclic/acyclic, Adjacency Matrix, ...