C语言——栈和队列

文章目录

  • 一、栈
    • 1. 栈的概念
    • 2. 栈的基本功能
    • 3. 栈的实现
  • 二、 队列
    • 1. 队列的概念
    • 2. 队列的基本功能
    • 3. 队列的实现

一、栈

1. 栈的概念

栈是一种特殊的线性表,限定仅在表尾进行插入和删除的线性表。这一端称之为栈顶,另一端称为栈底。
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
在这里插入图片描述

2. 栈的基本功能

// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

3. 栈的实现

栈的实现一般使用数组或者链表,因为cpu高速缓存的原因,使用数组也非常ok。

创建三个文件
头文件:
Stack.h
源文件:
Stack.c
test.c(测试功能是否能实现)

结构体的定义和函数声明:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

实现方法:

// 初始化栈 
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	//指向栈顶元素的下一个位置
	ps->top = 0;
	//top指向栈顶元素
	//ps->top = -1;
}

ps->a我们有两种初始化方法,一种是直接malloc一个空间,可以是四个或者八个对象的空间,也可以像我一样,先不开,等会入栈的时候再开。
在进行入栈以前,先把top指向为栈顶的下一个数据,如果指向栈顶数据的话,初始化就不能为0。
在这里插入图片描述

// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}
// 入栈 
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	//扩容
	
	if (ps->capacity == ps->top)
	{
		//初始化不开空间,当我插入数据时再开
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//用realloc因为在第一个指针为空时,realloc可以实现malloc的功能
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = data;//把数据直接放在top
	ps->top++;//top往后走到栈顶下一个数据

}
// 出栈 
void StackPop(Stack* ps)
{
	assert(ps);
	assert(ps->top > 0);//只有当栈不为空时才能出栈
	ps->top--;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}
/ 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top-1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

二、 队列

1. 队列的概念

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
在这里插入图片描述

2. 队列的基本功能

//初始化
void QueueInit(Queue* qp);
//销毁
void QueueDestroy(Queue* qp);
//队尾插入
void QueuePush(Queue* qp, QDatatype x);
//对头删除
void QueuePop(Queue* qp);
//取头和尾的数据
QDatatype QueueFront(Queue* qp);
QDatatype QueueBack(Queue* qp);
//获取队列元素个数
int QueueSize(Queue* qp);
//判空
bool QueueEmpty(Queue* qp);

3. 队列的实现

队列的实现用单链表就能很好的解决

创建三个文件
头文件:Queue.h
源文件:
Queue.c
test.c(测试功能是否能实现)

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDatatype;
typedef struct QNode
{
	struct Queue* next;
	QDatatype val;
}QNode;
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;//可以提高效率,删除就减去size,插入就增加size
}Queue;
//初始化Queue
//销毁
void QueueInit(Queue* qp);
void QueueDestroy(Queue* qp);
//void QueuePush(Queue** phead, Queue** ptail, QDatatype x);
//void QueuePop(Queue** phead, Queue** ptail);
//队尾插入和对头删除需要标记节点,还有更简便的方法,再创建一个结构体,名为Queue
//改变结构体的内容只需要传一级指针就行
//队尾插入
void QueuePush(Queue* qp, QDatatype x);
//对头删除
void QueuePop(Queue* qp);
//取头和尾的数据
QDatatype QueueFront(Queue* qp);
QDatatype QueueBack(Queue* qp);
//获取队列元素个数
int QueueSize(Queue* qp);
//判空
bool QueueEmpty(Queue* qp);
#define   _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
//初始化
//销毁
void QueueInit(Queue* qp)
{
	assert(qp);
	qp->phead = NULL;
	qp->ptail = NULL;
	qp->size = 0;
}
void QueueDestroy(Queue* qp)
{
	assert(qp);
	QNode* cur = qp->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	//释放完空间后需要把phead和ptail置空,不然就为野指针了
	qp->phead = NULL;
	qp->ptail = NULL;
	qp->size = 0;
}
//队尾插入
void QueuePush(Queue* qp, QDatatype x)
{
	assert(qp);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	newnode->next = NULL;
	newnode->val = x;
	//一个节点都没有
	if (qp->phead == NULL)
	{
		qp->phead = qp->ptail = newnode;
	}
	//有一个节点
	else
	{
		qp->ptail->next = newnode;//newnode成为新的尾
		qp->ptail = newnode;
	}
	qp->size++;
}
//对头删除
void QueuePop(Queue* qp)
{
	assert(qp);
	assert(qp->size != 0);
	if (qp->size == 1)//只剩一个节点
	{
		free(qp->phead);
		qp->phead = qp->ptail = NULL;//避免野指针
	}
	else//多个节点
	{
		QNode* next = qp->phead->next;
		free(qp->phead);
		qp->phead = next;
	} 
	qp->size--;
}
	//取头和尾的数据
QDatatype QueueFront(Queue * qp)
{
	assert(qp);
	return qp->phead->val;
}
QDatatype QueueBack(Queue * qp)
{
	assert(qp);
	assert(qp->phead);
	return qp->ptail->val;
}
int QueueSize(Queue* qp)
{
	assert(qp);
	assert(qp->ptail);
	return qp->size;//因为记录了size,所以直接返回size就行,不用遍历
}
bool QueueEmpty(Queue* qp)
{
	assert(qp);
	return qp->size == 0;
}

希望这篇博客对你有所帮助!!!
在这里插入图片描述

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

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

相关文章

运筹说 第114期 | 其他排队模型简介

前面我们已经学习了一些排队模型&#xff0c;对排队系统有了基本认知&#xff0c;本期小编带大家继续来学习其他排队模型的内容。 一、有限源排队模型 顾客源为有限的这类排队问题的主要特征是顾客总数是有限的&#xff0c;如只有m个顾客。每个顾客来到系统中接受服务后仍回到…

【网络安全】【Frida实战案例】某图xx付费功能逆向分析(二)

文章目录 一、目标应用二、环境三、步骤1、重打包2、运行打包后apk3、找到签名信息&#xff08;1&#xff09;、查看apk签名信息&#xff08;2&#xff09;、hook Android方法获取apk签名信息&#xff08;3&#xff09;、转为md5验证 4、hook apk签名信息 四、总结五、相关源码…

uniapp如何打包预约按摩H5?

uniapp如何打包预约按摩H5&#xff1f; 开发工具&#xff1a;HBuilderX 一、如何修改域名配置&#xff1f; 1、修改公众号AppID、页面访问路径 1&#xff09;gzh_appid: 公众号AppID siteroot: 域名&#xff0c;需更换为你自己的域名以及公众号APPID&#xff0c;域名格式【htt…

pandas style添加表格边框,或是只添加下边框等自定义边框样式设置

添加表格边框 可以使用如下程序添加表格&#xff1a; import dataframe_image as dfi import pandas as pd import numpy as npdf pd.DataFrame(np.random.random(size(10, 5))) df_style df.style.set_properties(**{text-align: center,border-color: black,border-width…

Filesystem Fragmentation on Modern Storage Systems——论文泛读

TOCS 2023 Paper 论文阅读笔记整理 问题 文件系统碎片是计算机系统随着时间的推移而变慢的主要原因之一。以前认为&#xff0c;碎片化对硬盘驱动器&#xff08;HDD&#xff09;等旋转存储设备有害&#xff0c;但不影响固态驱动器&#xff08;SSD&#xff09;&#xff0c;因为…

单链表题-ysf-反转-中间节点-回文-合并-分割

环形链表的约瑟夫问题_牛客题霸_牛客网 经典的约瑟夫环 #include <stdint.h> #include <stdlib.h> //创建链表 typedef struct ListNode ListNode;ListNode* buyNode(int x){ListNode* newNode(ListNode*)malloc(sizeof(ListNode));if(newNodeNULL){exit(1);}newN…

Facebook国内账户与 Facebook海外账户的区别

Facebook国内户的封户速度和频率有时可谓令人崩溃&#xff0c;为这种情况伤脑筋的朋友&#xff0c;不妨考虑一下Facebook海外户&#xff0c;既不限额&#xff0c;又更稳定..... Facebook&#xff0c;Google 开企业广告账户/游戏代投 &#xff0b;V:Ukvo77 TG&#xff1a;ukv…

AIGC——Instant-Style文本到图像生成中的样式保留算法解析

0.概述 在过去的几年中&#xff0c;基于调整的扩散模型在广泛的图像个性化和定制任务中取得了显着的进展。然而&#xff0c;尽管有潜力&#xff0c;当前基于调整的扩散模型在生成和生成风格一致的图像方面仍然面临着一系列复杂的挑战&#xff0c;其背后可能有三个原因。首先&a…

震惊!原来cmd命令行还可以这么玩?!

不论是在程序开发&#xff0c;还是遇到一些系统问题&#xff0c;我们很多时候会用到cmd命令行来处理问题&#xff0c;而当我们在执行cmd命令的时候&#xff0c;经常遇到下面这样的问题&#xff1a; ①. 控制台内容复制出来换行了 这种场景在我们安装nodejs插件的时候&#xff0…

项目管理表格-项目总体计划(项目管理-项目经理干货资料Excel)

项目管理总体计划模板 1、项目基本信息 2、项目里程碑 3、项目干系人 4、项目团队组织架构管理 5、项目预算管理 6、项目项目任务计划管理 7、问题及风险管理 8、项目周报 9、项目相关要求 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本…

如何实现Linux双网卡同时连接内网和外网的配置?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

百度百科怎么创建自己的公司

创建百度百科公司页面可以帮助提升企业知名度、提高搜索引擎排名、增强企业公信力、建立企业形象和行业权威。以下是创建公司百度百科的步骤&#xff1a; 准备阶段 收集资料 在开始撰写百度百科公司页面之前&#xff0c;首先需要收集公司的相关资料&#xff0c;包括公司的历史、…

社群推广遇见瓶颈?点这里,教你一招立马激活 | C1N短网址

社群推广在当下互联网营销里可是相当重要的一环啊&#xff0c;靠着社群的力量能迅速提升品牌知名度以及用户互动性。但在搞社群推广的过程中&#xff0c;那可是会碰到好多瓶颈的&#xff0c;这可让社群运营人员脑壳疼得很呐。 先来说说 01 社群人气不足&#xff1a;在社群推广中…

项目中使用Elasticsearch的API相关介绍

项目中使用Elasticsearch的API相关介绍 0、域映射类型 text&#xff1a;会分词&#xff0c;不支持聚合对当前搜索关键词&#xff0c;先自身分词&#xff0c;分成多个词&#xff0c;然后去一个一个的词去利用倒排索引去查询es索引库一般应用在搜索关键字匹配的字段的类型。 商…

电商数据分析的秘籍|数据采集渠道与工具|电商数据采集API接口

【数据采集渠道及工具选择】 进行电子商务数据分析与采集时常用的数据来源渠道有电子商务网站、店铺后台或平台提供的数据工具、政府部门、机构协会、媒体、权威网站数据机构、电子商务平台、指数工具等。

电子资源|基于SSM+vue的电子资源管理系统(源码+数据库+文档)​

电子资源管理系统 目录 基于SSMvue的电子资源管理系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&am…

C++ I/O流(一)——输出流

一、IO流概念 IO流可分为输入流和输出流,用于从设备(如键盘、文件、网络等)读取数据或向设备写入数据。C++标准库提供了丰富的IO流类,包括iostream、fstream、stringstream等,分别用于处理控制台输入输出、文件输入输出和字符串流操作。 读操作:输入流中读取数据到程序中…

Nginx配置文件conf解释

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nginx(“engine x”…

PHP黑魔法之strcmp与is_numeric绕过

1、strcmp绕过 PHP手册: int strcmp ( string $str1 , string $str2 )Return ValuesReturns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal 当输入的两个值为不是字符串时就会产生不预期的返回值 strcmp()在比较字符串和…

Java中的数据类型与变量

引言&#xff1a; 哈喽&#xff0c;各位读者老爷们大家好呀,long time no see!这里是小堇Java小课堂&#xff0c;在本课堂中我们将继续分享Java中的数据类型与变量&#xff0c;标识符&#xff0c;关键字等知识&#xff0c;那我们启程咯&#xff01; 数据类型与变量 1.字面变量…