C语言实现堆栈和队列(动态)

news2024/11/24 16:53:11

行路难!行路难!多歧路,今安在?长风破浪会有时,直挂云帆济沧海。————李白


一  .堆栈

1 什么是堆栈

堆栈是一种特殊的线性表,堆栈中的元素以及元素之间的逻辑关系和线性表完全相同。在操作上的差别是线性表允许在任意位置插入和删除元素,而堆栈只允许在固定一端插入和删除元素,堆栈中允许插入和删除元素的一端称为栈顶,另一端称为栈底

栈顶的当前位置是动态的,用于标记栈顶当前位置的变量,称为栈顶指示器。堆栈的插入操作,通常称为入栈。堆栈的删除操作通常称为出栈

根据堆栈的定义,我们可以发现,每次入栈的元素都放在原栈顶元素之前而成为新的栈顶元素,每次出栈的元素都是原栈顶元素。这样最后进入栈的元素总是最先退出栈的,因此堆栈也称作后进先出的线性表,或简称为后进先出表。 


2 堆栈的两种实现方式

栈的实现一般可以使用数组或者链表实现

链式栈:用链表的结构来实现栈。

顺序栈:用数组的结构来实现栈。

优缺点:

单向链式结构的出栈入栈效率比较低,因为我们要先找到尾结点再行插入删除

而顺序栈只需要记录栈顶位置,进行出栈入栈十分方便,不需要多余的空间存储地址。

所以相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。


3 堆栈的操作实现

3.1 栈的结构体和初始化

结构体:

#pragma once

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

初始化:

void StackInit(ST* ps)
{
	assert(ps);

	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	ps->capacity = 4;
	ps->top = 0;
}
3.2 销毁
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

3.3入栈
// 入栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	// 满了-》增容
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			ps->a = tmp;
			ps->capacity *= 2;
		}
	}

	ps->a[ps->top] = x;
	ps->top++;
}
3.4出栈
// 出栈
void StackPop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Pop,直接中止程序报错
	assert(ps->top > 0);

	//ps->a[ps->top - 1] = 0;
	ps->top--;
}
3.5判断栈是否为空
bool StackEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}
3.6取顶部数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Top,直接中止程序报错
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}
3.7取栈中有效数据的个数
int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

4 完整代码

Stack.h
#pragma once

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int STDataType;


typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void StackInit(ST* ps);

void StackDestory(ST* ps);
// 入栈
void StackPush(ST* ps, STDataType x);
// 出栈
void StackPop(ST* ps);

STDataType StackTop(ST* ps);

int StackSize(ST* ps);

bool StackEmpty(ST* ps);
Stack.c
#include "Stack.h"

void StackInit(ST* ps)
{
	assert(ps);

	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	ps->capacity = 4;
	ps->top = 0;
}

void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

// 入栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	// 满了-》增容
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			ps->a = tmp;
			ps->capacity *= 2;
		}
	}

	ps->a[ps->top] = x;
	ps->top++;
}

// 出栈
void StackPop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Pop,直接中止程序报错
	assert(ps->top > 0);

	//ps->a[ps->top - 1] = 0;
	ps->top--;
}

STDataType StackTop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Top,直接中止程序报错
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool StackEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

二 .队列

1 队列的概念及结构

队列也是一种特殊的线性表,队列中的元素及元素间的逻辑关系和线性表完全相同,在操作上的差异是; 线性表允许在任意位置插入和删除元素。而队列只允许在其一端进行插入操作,在其另一端进行删除操作。

在队列中,允许进行插入操作的一端成为队尾。允许进行删除操作的一端成为队头,队头队尾,分别由队头指针和队尾指针指示。队列的插入操作通常称作入队列,队列的删除操作通常称作出队列,根据队列的定义,我们可以把,队列想象成是一种先进先出的线性表,简称先进先出表

 

2 队列的实现形式

队列也可以数组和链表的结构实现,但使用链表的结构实现更优一些,因为如果使用数组的结构, 出队列在数组头上出数据,效率会比较低。

3 队列的操作实现

3.1  结构体
typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;
3.2  队列初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
3.3  队列的销毁
void QueueDestory(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}
3.4  入队列(队尾入)
// 队尾入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
 3.5  出队列(队头出)
// 队头出
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);


	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
3.6  删除队内数据
3.6.1  前删
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}
3.6.2  尾删
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->tail->data;
}
3.7  返回队列大小
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		++size;
		cur = cur->next;
	}

	return size;
}
3.8  清空队列 
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

4 完整代码

queue.h:
#define _CRT_SECURE_NO_WARNINGS
#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;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

//队列初始化
void QueueInit(Queue* pq);

//队列销毁
void QueueDestory(Queue* pq);

// 队尾入
void QueuePush(Queue* pq, QDataType x);

// 队头出
void QueuePop(Queue* pq);

//前删
QDataType QueueFront(Queue* pq);

//后删
QDataType QueueBack(Queue* pq);

//队列大小
int QueueSize(Queue* pq);

//清空队列
bool QueueEmpty(Queue* pq);

queue.c:
#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}

// 队尾入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

// 队头出
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);


	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}


QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->tail->data;
}

int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		++size;
		cur = cur->next;
	}

	return size;
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 2.7 在 Debian 服务器上获取 URL 时的 SSL 验证失败问题与解决方案

在使用Python的requests库从Debian稳定服务器上获取简单URL时&#xff0c;遇到了SSL证书错误。 根据用户的问题描述&#xff0c;您遇到了SSL证书验证失败的问题。 要解决这个问题&#xff0c;您可以采取以下步骤&#xff1a; 1. 升级到Python 2.7的最新版本&#xff1a; 首…

《程序员考公指南》:零基础到上岸的完整攻略 | 开源日报 No.82

mastodon/mastodon Stars: 44.2k License: AGPL-3.0 Mastodon 是一个免费、开源的社交网络服务器&#xff0c;基于 ActivityPub。用户可以在 Mastodon 上关注朋友并发现新朋友&#xff0c;并且可以发布链接、图片、文字和视频等内容。所有的 Mastodon 服务器都能互操作成为联邦…

使用vue-cli搭建vue项目

1&#xff1a;安装vue-cli 命令&#xff1a;npm install -g vue/cli 2&#xff1a;查看安装的版本 vue --version 或者 vue -V 3&#xff1a;创建项目 vue create 项目名称 名称小写 4&#xff1a;vue2框架中根据自己的需求选择&#xff08;我选择…

Rust语言特性探秘:宏的魔力

大家好&#xff01;我是lincyang。 今天我们继续深入探讨Rust语言中的一个有趣而强大的特性——宏&#xff08;Macros&#xff09;。 宏在Rust中扮演着特殊的角色&#xff0c;不仅提高了代码的灵活性&#xff0c;还增强了代码的可重用性。接下来&#xff0c;我们会通过具体的…

java+springboot+bootstrap校园闲置物品拍卖交易平台_ngad7-

根据日常实际需要&#xff0c;一方面需要在系统中实现基础信息的管理&#xff0c;同时还需要结合实际情况的需要&#xff0c;提供校园闲置物品交易管理功能&#xff0c;方便校园闲置物品交易管理工作的展开&#xff0c;综合考虑&#xff0c;本套系统应该满足如下要求&#xff1…

springboot+jsp+bootstrap+java问卷调查系统

系统功能需求包含业务需求和功能需求&#xff0c;系统功能需求分析是在了解用户习惯、开发人员技术和实力等各个因素的前提下&#xff0c;对其进行深入分析&#xff0c;了解系统基本需求后&#xff0c;基本功能如下&#xff1a; 本课题要求实现优质的问卷调查系统&#xff0c;就…

如何录音?学会这几招,轻松搞定!

“有人知道怎么录音吗&#xff1f;学校举办了诗词朗诵比赛&#xff0c;老师要求我代表班级去参加&#xff0c;需要自己准备一首比赛主题相关的背景音乐&#xff0c;可是找到的音乐都不能下载&#xff0c;我也不会录音&#xff0c;真的很难办&#xff0c;大家有什么好方法吗&…

NX二次开发UF_CAM_opt_ask_post_names 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_opt_ask_post_names Defined in: uf_cam.h int UF_CAM_opt_ask_post_names(int * count, const char * * * names ) overview 概述 This function provides a list of avai…

vatee万腾科技先锋之选:vatee创新力驱动着未来发展

在科技潮流的浩荡前行中&#xff0c;Vatee万腾崭新的科技先锋之选正以强大的创新力引领着未来的发展。Vatee万腾凭借其前瞻性的技术理念和卓越的创新实践&#xff0c;成为业界的引领者&#xff0c;为整个科技行业树立了标杆。 Vatee万腾不仅仅是一家科技公司&#xff0c;更是一…

【云栖 2023】姜伟华:Hologres Serverless 之路——揭秘弹性计算组

云布道师 本文根据 2023 云栖大会演讲实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;姜伟华 | 阿里云计算平台事业部资深技术专家、阿里云实时数仓 Hologres 研发负责人 演讲主题&#xff1a;Hologres Serverless 之路——揭秘弹性计算组 实时化成为…

基于安卓android微信小程序的刷题系统

项目介绍 面试刷题系统的开发过程中&#xff0c;采用B / S架构&#xff0c;主要使用jsp技术进行开发&#xff0c;中间件服务器是Tomcat服务器&#xff0c;使用Mysql数据库和Eclipse开发环境。该面试刷题系统包括会员、答题录入员和管理员。其主要功能包括管理员&#xff1a;个…

Unsupervised Condition GAN

Unsupervised Condition GAN主要有两种做法&#xff1a; Direct Transformation 直接输入domain X图片&#xff0c;经过Generator后生成对应的domain Y的图像。这种转化input和output不能够差太多。通常只能实现较小的转化&#xff0c;比如改变颜色等。 Projection to Commo…

怎么做好品牌营销,小红书爆款笔记怎么做?

只要在小红书平台进行传播&#xff0c;能够尽可能多的创造爆款笔记&#xff0c;就是所有品牌方和达人的目标。今天来马文化传媒为大家分享下怎么做好品牌营销&#xff0c;小红书爆款笔记怎么做&#xff1f; 一、判断爆款笔记的三大指标 判断一篇笔记是否是爆款笔记&#xff0c;…

Rockchip平台rk3588源码下载编译(基于Android13)

Rockchip平台rk3588源码下载编译(基于Android13) 源码下载 下载地址 repo init --repo-url https://gerrit.rock-chips.com:8443/repo-release/tools/repo -u https://gerrit.rock-chips.com:8443/Android_T/manifests.git -m Android13.xml服务器镜像下载 repo init --rep…

深度之眼Paper带读笔记GNN.08.GCN(下)

文章目录 前言细节四&#xff1a;卷积核介绍图卷积核初代目图卷积核二代目契比雪夫多项式例子小结 GCN公式推导 实验设置和结果分析数据集节点分类任务消息传递方式比较运行效率 总结关键点创新点启发点 代码复现train.pyutil.pymodel.pylayer.py 作业 前言 本课程来自深度之眼…

图形数据库的实战应用:如何在 Neo4j 中有效管理复杂关系

关系数据库管理系统( RDBMS ) 代表了最先进的技术&#xff0c;这在一定程度上要归功于其由周边技术、工具和广泛的专业技能组成的完善的生态系统。 在这个涵盖信息技术(IT) 和运营技术(OT) 的技术革命时代&#xff0c;人们普遍认识到性能方面出现了重大挑战&#xff0c;特别是…

springboot+bootstrap+java农业电商服务商城系统_30249

本农业电商服务系统是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了管理员、会员和商家这三者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能…

鸿蒙原生应用/元服务开发-AGC分发如何编译打包应用

软件包规范 在正式打包应用前&#xff0c;请确保已了解HarmonyOS应用软件包规范。 操作步骤 1.打开DevEco Studio&#xff0c;菜单选择“Build > Build Hap(s)/APP(s) > Build APP(s)”。 2.等待编译构建。编译完成后&#xff0c;将在工程目录“build > outputs >…

企业再不做数字化就OUT了

做数字化是为了让企业活得更好&#xff0c;也是企业活下去的关键&#xff01; 今年是十四五规划的第二年&#xff0c;科技创新与数字生态建设&#xff0c;俨然成为今年政府工作报告中重点强调的方向之一。 “加快数字化发展&#xff0c;打造数字经济新优势&#xff0c;协同推进…

喜报 | 热烈祝贺思腾合力成功挂牌天津OTC专精特新板

近日&#xff0c;天津区域性股权市场企业挂牌上市成果发布会于2023中国民营企业投融资洽谈会上成功举行。在会上公布&#xff0c;思腾合力成功挂牌天津OTC“专精特新”板。 本次活动由北交所&#xff08;新三板&#xff09;天津基地、天津证监局、市发改委&#xff0c;天津滨海…