【数据结构】栈和队列---C语言版

栈和队列

  • 一、栈的概念
  • 二、栈的实现
  • 三、栈的应用
  • 四、队列的概念
  • 五、队列的实现

一、栈的概念

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

二、栈的实现

1.头文件:

#define  _CRT_SECURE_NO_WARNINGS  1
#pragma once
#include<stdbool.h>
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
 
typedef int STDataType;
 
struct Stack
{
	STDataType* a;
	int top;//栈顶,top指向最后一个数据的下一个位置
	int capacity;//容量,方便增容
};
 
typedef struct Stack Stack;
 
//初始化
void StackInit(Stack* pst);
 
//销毁
void StackDestroy(Stack* pst);
 
//栈顶插入元素
void StackPush(Stack* pst, STDataType x);
 
//栈顶删除元素
void StackPop(Stack* pst);
 
//取栈顶元素
STDataType StackTop(Stack* pst);
 
//判断栈空
bool StackEmpty(Stack* pst);
 
//求栈元素个数
int StackSize(Stack* pst);

2.源文件:

#include "039-Stack.h"
 
//初始化
void StackInit(Stack* pst)
{
	assert(pst);
	pst->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	pst->top = 0;
	pst->capacity = 4;
}
 
//销毁
void StackDestroy(Stack* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}
 
//插入元素
void StackPush(Stack* pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * pst->capacity * 2);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		pst->a = tmp;
		pst->capacity *= 2;
	}
 
	pst->a[pst->top] = x;
	pst->top++;
}
 
//删除元素
void StackPop(Stack* pst)
{
	assert(pst);
	assert(!StackEmpty(pst));
	pst->top--;
}
 
//返回栈顶元素
STDataType StackTop(Stack* pst)
{
	assert(pst);
	assert(!StackEmpty(pst));
	return pst->a[pst->top - 1];
}
 
//判断栈是否已满,空返回1,非空返回0
bool StackEmpty(Stack* pst)
{
	assert(pst);
	return pst->top == 0;
}
 
//求栈中元素个数
int StackSize(Stack* pst)
{
	assert(pst);
	return pst->top;
}

3.测试文件:

#define  _CRT_SECURE_NO_WARNINGS  1
#include "039-Stack.h"
 
void TestStack()
{
	Stack st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
 
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	
	StackDestroy(&st);
 
}
int main()
{
	TestStack();
	return 0;
}

三、栈的应用

1.有效的括号:链接

分析:

(1)将栈的实现可以直接copy进去(返回栈顶元素需要做小小的改动:如果栈为空,不能直接assert断言终止,而要返回’\0’),后面只需要实现括号的匹配即可。

(2)如何实现括号匹配?如果是左括号,那么入栈,如果是右括号就判断栈顶元素该右括号是否能够匹配,如果可以就从栈里弹出一个左括号,如果不匹配就直接返回false。

char pairs(char a) {
    if (a == '}') return '{';
    if (a == ']') return '[';
    if (a == ')') return '(';
    return 0;
}

bool isValid(char* s) {
    int n = strlen(s);
    if (n % 2 == 1) {
        return false;
    }
    int stk[n + 1], top = 0;
    for (int i = 0; i < n; i++) {
        char ch = pairs(s[i]);
        if (ch) {
            if (top == 0 || stk[top - 1] != ch) {
                return false;
            }
            top--;
        } else {
            stk[top++] = s[i];
        }
    }
    return top == 0;
}

四、队列的概念

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

五、队列的实现

1.头文件:

#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
 
typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QueueNode;
 
typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;
 
//初始化
void QueueInit(Queue* pq);
 
//销毁
void QueueDestroy(Queue* pq);
 
//插入数据
void QueuePush(Queue* pq, QDataType x);
 
//删除数据
void QueuePop(Queue* pq);
 
//取队头数据
QDataType QueueFront(Queue* pq);
 
//取队尾数据
QDataType QueueRear(Queue* pq);
 
//判断队是否已满
bool QueueEmpty(Queue* pq);
 
//求队列元素个数
int QueueSize(Queue* pq);

2.源文件:

#define  _CRT_SECURE_NO_WARNINGS  1
#include "040-Queue.h"
 
//初始化
void QueueInit(Queue* pq)
{
	pq->head = pq->tail = NULL;
}
 
//销毁
void QueueDestroy(Queue* pq)
{
	QueueNode* cur = pq->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}
 
//插入数据
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newNode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
 
	newNode->data = x;
	newNode->next = NULL;
 
	//插入一个数据,尾指针+1,当尾指针为空时,队列为空
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}
 
//删除数据
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
 
//取队头数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
 
	return pq->head->data;
}
 
//取队尾数据
QDataType QueueRear(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
 
	return pq->tail->data;
}
 
//判断队是否已满
bool QueueEmpty(Queue* pq)
{
	assert(pq);
 
	return pq->head == NULL;
}
 
//求队列元素个数
int QueueSize(Queue* pq)
{
 
	int size = 0;
	QueueNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
 
}

3.测试文件:

#define  _CRT_SECURE_NO_WARNINGS  1
#include"040-Queue.h"
void TestQueue()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
 
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
 
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
 
	QueuePush(&q, 3);
	QueuePush(&q, 4);
 
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
 
	printf("\n");
 
	QueueDestroy(&q);
}
 
int main()
{
	TestQueue();
}

好了,今天的分享就到这里了
如果对你有帮助,记得点赞👍+关注哦!
我的主页还有其他文章,欢迎学习指点。关注我,让我们一起学习,一起成长吧!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索抖音小店:新手适合的热门类目和成功经营策略详解

抖音小店是一个电商平台&#xff0c;提供了多个类目供商家选择。四川不若与众将介绍一些常见的抖音小店类目&#xff0c;并提供适合新手的类目建议。 1. 美妆护肤类&#xff1a;这是抖音平台上非常热门的类目之一。包括化妆品、护肤品、美容工具等。美妆护肤品受到女性用户的高…

【Android Jetpack】Room数据库

文章目录 引入EntitiesPrimary Key主键索引和唯一性对象之间的关系外键获取关联的Entity对象嵌套对象Data Access Objects&#xff08;DAOs&#xff09;使用Query注解的方法简单的查询带参数查询返回列的子集可被观察的查询 数据库迁移用法 引入 原始的SQLite有以下两个缺点: …

RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(基于SpringBoot)

文章目录 前言一、WorkQueues模型消息发送消息接收能者多劳 二、交换机类型1.Fanout交换机消息发送消息接收 2.Direct交换机消息接收消息发送 3.Topic交换机消息发送消息接收 三、编程式声明队列和交换机fanout示例direct示例基于注解 四、消息转换器总结 前言 WorkQueues模型…

基于UDP的TFTP文件传输

代码&#xff1a; #include <myhead.h>//实现下载功能 int download(int cfd,struct sockaddr_in sin) {char buf[516] ""; //定义资源包char fileName[128] ""; //定义文件名printf("请输入文件名:");scanf("%s",fileName…

Rocky Linux 9.3 为 PowerPC 64 位带回云和容器镜像

RHEL 克隆版 Rocky Linux 9.3 今天发布了&#xff0c;作为红帽企业 Linux 发行版 CentOS Stream 和 Red Hat Enterprise Linux 的免费替代版本&#xff0c;现在可供下载。 Rocky Linux 9.3 是在 Rocky Linux 9.2 发布 6 个月之后发布的&#xff0c;它带回了 PowerPC 64 位 Lit…

Java核心知识点整理大全22-笔记

目录 19.1.14. CAP 一致性&#xff08;C&#xff09;&#xff1a; 可用性&#xff08;A&#xff09;&#xff1a; 分区容忍性&#xff08;P&#xff09;&#xff1a; 20. 一致性算法 20.1.1. Paxos Paxos 三种角色&#xff1a;Proposer&#xff0c;Acceptor&#xff0c;L…

MySQL修改已存在数据的字符集

在实际应用中&#xff0c;如果一开始没有正确的设置字符集&#xff0c;在运行一段时间以后&#xff0c;才发现当前字符集不能满足要求&#xff0c;需要进行调整&#xff0c;但又不想丢弃这段时间的数据&#xff0c;这个时候就需要修改字符集。 在MySQL设置默认字符集和校对规则…

【飞桨星河社区五周年线下工坊-杭州站】

? 欢迎大家参加杭州极客工坊&#xff0c;深入了解大模型前沿技术和创新应用&#xff0c;一站式体验AI原生应用开发? 精彩议程敬请期待&#xff5e; ? 时间&#xff1a;2023年12月3日 14:00-17:30 ? 地点&#xff1a;杭州西湖区花蒋路3号西溪润泽园度假酒店 ? 主题&#xf…

C++中用于动态内存的new和delete操作符

文章目录 1、动态分配内存的应用2、动态分配内存与分配给普通变量的内存有什么不同?3、C 中如何分配/释放内存4、new 操作符4.1 使用new的语法4.2 初始化内存4.3 分配内存块4.4 普通数组声明 Vs 使用new4.5 如果运行时没有足够内存可用怎么办&#xff1f; 5、delete 操作符 C/…

第二十章Java博客

如果一次只完成一件事情&#xff0c;很容易实现。但现实生活中&#xff0c;很多事情都是同时进行的。Java中为了模拟这种状态&#xff0c;引入了线程机制。简单地说&#xff0c;当程序同时完成多件事情时&#xff0c;就是所谓的多线程。多线程应用相当广泛&#xff0c;使用多线…

喜报 | 再获影响力产品奖!擎创科技实力亮相GOPS全球运维大会

10月26日-27日&#xff0c;为期两天&#xff0c;共1100余人签到的 GOPS 全球运维大会 2023 上海站已经圆满落幕。 此次会议的“2023 IT技术领导力年度颁奖典礼”中&#xff0c;擎创夏洛克AIOps数智运维管理平台凭借成熟的产品能力及广泛且优异的落地实践效益&#xff0c;得到了…

记 Doris 回归测试S3导入load_parallelism > 1

增加load_parallelism > 1的S3导入用例&#xff0c;测试导入时切分输入文件的逻辑。 这里有几个隐性的问题点&#xff08;坑&#xff09;&#xff1a; 1、导入的文件一定要大&#xff0c;一般大于128M&#xff0c;否则&#xff0c;即使设置了 load_parallelism > 1 也不…

AI搜索相关性在网站和APP上的应用

设定场景&#xff1a;您在寻找一件新衣服&#xff0c;所以在浏览最喜欢的网店。您跳到搜索栏上&#xff0c;输入您要找的东西。您期待出现什么结果&#xff1f; 高度准确、相关和即时的结果。 无论在什么网站上搜索&#xff0c;寻找什么&#xff0c;甚至在打错字或使用了错误的…

JAVA进阶之路JVM-3:JVM内存模型,运行时数据区域划分,程序计数器,虚拟机栈,本地方法栈,堆,元空间,字符串常量池

JVM内存模型 对于 Java 程序员来说&#xff0c;在虚拟机自动内存管理机制下&#xff0c;不再需要像 C/C 程序开发程序员这样为每一个操作去写对应的 delete / free 操作&#xff0c;不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序把内new存控制权利交给JVM虚拟机。一旦…

从源码解析Containerd容器启动流程

从源码解析Containerd容器启动流程 本文从源码的角度分析containerd容器启动流程以及相关功能的实现。 本篇containerd版本为v1.7.9。 更多文章访问 https://www.cyisme.top 本文从ctr run命令出发&#xff0c;分析containerd的容器启动流程。 ctr命令 查看文件cmd/ctr/comman…

高档建筑覆膜板,胶水足表面光滑

在建筑材料行业&#xff0c;选择高质量的建筑覆膜板至关重要。贵港市能强优品木业是专业从事建筑覆膜板生产销售25年的源头工厂。这家工厂一直以来致力于生产出色的覆膜板&#xff0c;以确保建筑物外观精美&#xff0c;持久耐用。 无论是商业大楼还是家庭住宅&#xff0c;外墙装…

气膜建筑助力体育场馆快速普及

传统的室内体育馆投入资金庞大&#xff0c;建设强度高&#xff0c;建设周期漫长。而气膜体育馆的出现&#xff0c;不仅显著降低了建设成本和缩短了建设周期&#xff0c;更符合节能环保的需求&#xff0c;成为推动场馆快速普及的创新建筑形式。 对于校园设施的建设而言&#xff…

可以免费使用的Axure在线版来了

Axure作为一种功能强大的原型设计工具&#xff0c;一直受到设计师的青睐。然而&#xff0c;其高昂的价格可能成为一个门槛&#xff0c;限制了一些设计师的选择。但不用担心&#xff0c;现在有一个免费的Axure在线工具即时设计&#xff0c;功能更完整&#xff0c;更划算&#xf…

『 MySQL数据库 』插入查询结果

文章目录 &#x1f39f;️ 前言&#x1f39f;️ 创建一张结构相同的表&#x1f39f;️ 表内插入查询结果&#x1f3ab; 对表内数据进行去重&#x1f3ab; 配合ORDER BY排序后以及LIMIT分页对数据进行插入 &#x1f39f;️ 前言 在MySQL数据库中不仅可以直接根据字段类型等对数据…

信而泰 SSL测试方法介绍

[本文介绍在ALPS平台上进行SSL测试的内容和方法] 什么是SSL SSL全称是Secure Sockets Layer&#xff0c;指安全套接字协议&#xff0c;为基于TCP的应用层协议提供安全连接&#xff1b;SSL介于TCP/IP协议栈的第四层和第五层之间&#xff0c;广泛用于电子商务、网上银行等。 SSL…