数据结构之栈和队列

news2025/7/22 5:28:34

目录

1.栈的概念2、栈的实现

1、队列的概念2、队列的实现

今天介绍的是栈和队列。

先说栈吧。

1.栈的概念

栈也是线性表的一种,不过他较为特殊。他只能在一边进行数据的出入。也就是说晚进的数据先出去。进行数据进出的一端叫做栈顶,另一端叫做栈底。

数据进入叫做压栈,数据出去叫做出栈。

 

从图中可以看出,栈的数据进出遵循后进先出的规则。

2、栈的实现

栈的实现可以使用数组也可使用链表。在这里我们使用数组,因为栈的数据进出本质是尾插尾删,而用链表实现,尾插与尾删还得先找到尾,相对于数组较为复杂。所以在这里选择数组。

栈有分为静态栈与动态增长的栈。

静态栈

 

在实际中相对不实用,所以在这里实现可以动态增长的栈。

这次我们实现的接口有:栈的初始化,压栈,出栈,返回栈顶数据,返回栈中数据个数,检验栈是否为空,销毁栈。

结构体创建:

typedef int Datatype;
typedef struct StackList
{
	Datatype* arr;
	Datatype top;// 初始为0,表示栈顶位置下一个位置下标
	Datatype capacity;
}SL;

初始化:

void initialize(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	slnum->arr = NULL;
}

扩容:

void expand(SL* slnum)
{
	assert(slnum);

	if(slnum->capacity == slnum->top)
	{
		Datatype newcapacity = slnum->capacity = 0 ? 4 : slnum->capacity * 2;
		SL* tmp = (SL*)realloc(slnum->arr,sizeof(Datatype) * newcapacity);
		if(tmp == NULL)
		{
			perror("realloc false");
			exit(-1);
		}
		slnum->arr = tmp;
		slnum->capacity = newcapacity;
	}
}

压栈:

void stackint(SL* slnum,Datatype n)
{
	expand(slnum);
	slnum->arr[slnum->top] = n;
	slnum->top++;
}

出栈:

void stackout(SL* slnum)
{
	assert(slnum);

	assert(slnum->top > 0);
	slnum->top--;
}

栈中元素个数:

Datatype stacktop(SL* slnum)
{
	assert(slnum);
	assert(!stackempty);
	return slnum->top-1;
}

获取栈顶:

Datatype get_stacktop(SL* slnum)
{
	assert(slnum);

	assert(!stackempty);

	return slnum->arr[slnum->top - 1];
}

检验栈是否为空:

bool stackempty(SL* slnum)
{
	assert(slnum);

	if (slnum->top > 0)
	{
		return true;
	}
	else
		return false;
}

销毁栈:

void destroy(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	free(slnum->arr);
	slnum->arr = NULL;
}

栈的介绍就到这里,下面开始介绍队列。

1、队列的概念

队列是在一端插入数据在另一端删除数据的线性表。队列的数据删除规则为先进先出。队列在队尾插入,在对头删除。

 2、队列的实现

队列的实现也可以使用数组,也可以使用链表,又因为使用数组实现队列时删除数据需要挪动数据因此在这里我们使用链表来实现队列。

因为我们在实现队列时需要在队头出队,在队尾入队。所以我们可以再次封装一个结构体变量,里面放入一个head指针,一个tail指针。

typedef int Qdatatype;
typedef struct QueueNode
{
	Qdatatype n;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

接口实现:

初始化:

void QInit(struct Queue* p)
{
	assert(p);
	p->head = NULL;
	p->tail = NULL;

	p->size = 0;

}

队尾入队列:

void Queueint(Queue* p,Qdatatype n)
{
	assert(p);

	QNode* tmp = (QNode*)malloc(sizeof(QNode));

	QNode* tmp = (QNode*)malloc(p, sizeof(QNode));

	if(tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	tmp->n = n;
	tmp->next = NULL;
	p->size++;
	if( p->tail == NULL)
	{
		p->head = p->tail = tmp;
	}
	else
	{
		p->tail->next = tmp;
		p->tail = p->tail->next;
	}
}

队头出队列:

void Queueout(Queue* p)
{
	assert(p);
	assert(!Queueempty(p));
	if(p->head->next == NULL)
	{
		free(p->head);
		p->head = p->tail = NULL;
	}
	else
	{
		QNode* tmphead = p->head;
		p->head = p->head->next;
		free(tmphead);
	}
	
	p->size--;

}

判断队列是否为空:

bool Queueempty(Queue* p)
{
	return p->head == NULL&&p->tail == NULL;
}

获取队头数据:

Qdatatype Gettop(Queue* p)
{
	assert(p);

	assert(!Queueempty(p));

	assert(!queueempty(p));

	printf("%d ", p->head->n);
}

获取队尾数据:

Qdatatype Gettail(Queue* p)
{
	assert(p);

	assert(!Queueempty(p));

	assert(!queueempty(p));

	printf("%d ", p->tail->n);
}

有效数据个数:

Qdatatype Count(Queue* p)
{
	return p->size;
}

销毁队列:

void destroy(Queue* p)
{
	assert(p);
	QNode* cur = p->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	free(p->head);
	free(p->tail);


}

3、完整版代码

栈:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int Datatype;
typedef struct StackList
{
	Datatype* arr;
	Datatype top;// 初始为0,表示栈顶位置下一个位置下标
	Datatype capacity;
}SL;

//接口功能实现
//初始化
void initialize(SL* slnum);
//扩容
void expand(SL* slnum);
//入栈
void stackint(SL* slnum,Datatype n);
//出栈
void stackout(SL* slnum);
//获取栈有效元素个数
Datatype stacktop(SL* slnum);
//获取栈顶元素
Datatype get_stacktop(SL* slnum);
//检查栈是否为空
bool stackempty(SL* slnum);
//销毁
void destroy(SL* slnum);
#pragma once
#include"stacklist.h"
void initialize(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	slnum->arr = NULL;
}
void expand(SL* slnum)
{
	assert(slnum);

	if(slnum->capacity == slnum->top)
	{
		Datatype newcapacity = slnum->capacity = 0 ? 4 : slnum->capacity * 2;
		SL* tmp = (SL*)realloc(slnum->arr,sizeof(Datatype) * newcapacity);
		if(tmp == NULL)
		{
			perror("realloc false");
			exit(-1);
		}
		slnum->arr = tmp;
		slnum->capacity = newcapacity;
	}
}
void stackint(SL* slnum,Datatype n)
{
	expand(slnum);
	slnum->arr[slnum->top] = n;
	slnum->top++;
}
void stackout(SL* slnum)
{
	assert(slnum);

	assert(slnum->top > 0);
	slnum->top--;
}
Datatype stacktop(SL* slnum)
{
	assert(slnum);
	assert(!stackempty);
	return slnum->top-1;
}
Datatype get_stacktop(SL* slnum)
{
	assert(slnum);

	assert(!stackempty);

	return slnum->arr[slnum->top - 1];
}
bool stackempty(SL* slnum)
{
	assert(slnum);

	if (slnum->top > 0)
	{
		return true;
	}
	else
		return false;
}
void destroy(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	free(slnum->arr);
	slnum->arr = NULL;
}

队列:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int Qdatatype;
typedef struct QueueNode
{
	Qdatatype n;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

//初始化
void QInit(struct Queue* p);
// 队尾入队列
void Queueint(Queue* p, Qdatatype n);
// 队头出队列
void Queueout(Queue* p);
// 获取队列头部元素
Qdatatype Gettop(Queue* p);
// 获取队列队尾元素
Qdatatype Gettail(Queue* p);
// 获取队列中有效元素个数
Qdatatype Count(Queue* p);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool Queueempty(Queue* p);
// 销毁队列
void destroy(Queue* p);
#include"queue.h"
void QInit(struct Queue* p)
{
	assert(p);
	p->head = NULL;
	p->tail = NULL;
<<<<<<< HEAD
	p->size = 0;
=======
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
}
void Queueint(Queue* p,Qdatatype n)
{
	assert(p);
<<<<<<< HEAD
	QNode* tmp = (QNode*)malloc(sizeof(QNode));
=======
	QNode* tmp = (QNode*)malloc(p, sizeof(QNode));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	if(tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	tmp->n = n;
	tmp->next = NULL;
	p->size++;
	if( p->tail == NULL)
	{
		p->head = p->tail = tmp;
	}
	else
	{
		p->tail->next = tmp;
		p->tail = p->tail->next;
	}
}
bool Queueempty(Queue* p)
{
	return p->head == NULL&&p->tail == NULL;
}
void Queueout(Queue* p)
{
	assert(p);
	assert(!Queueempty(p));
	if(p->head->next == NULL)
	{
		free(p->head);
		p->head = p->tail = NULL;
	}
	else
	{
		QNode* tmphead = p->head;
		p->head = p->head->next;
		free(tmphead);
	}
	
	p->size--;

}
Qdatatype Gettop(Queue* p)
{
	assert(p);
<<<<<<< HEAD
	assert(!Queueempty(p));
=======
	assert(!queueempty(p));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	printf("%d ", p->head->n);
}
Qdatatype Gettail(Queue* p)
{
	assert(p);
<<<<<<< HEAD
	assert(!Queueempty(p));
=======
	assert(!queueempty(p));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	printf("%d ", p->tail->n);
}
Qdatatype Count(Queue* p)
{
	return p->size;
}
void destroy(Queue* p)
{
	assert(p);
	QNode* cur = p->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	free(p->head);
	free(p->tail);


}

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

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

相关文章

从ReentrantReadWriteLock开始的独占锁与共享锁的源码分析

FBI WARNING&#xff08;bushi&#xff09; 当涉及sync调用时&#xff0c;并不会分析尝试获取和释放之后的后继逻辑&#xff0c;因为这个逻辑是由AQS类实现的。请看姊妹篇之并发入门组件AQS源码解析。 开始的开始是一个demo 以下的代码&#xff0c;会将独占锁持有5分钟&…

【LSTM实战】股票走势预测全流程实战(stock predict)

任务&#xff1a;利用LSTM模型预测2017年的股票中High的走势&#xff0c;并与真实的数据进行比对。数据&#xff1a;https://www.kaggle.com/datasets/princeteng/stock-predict 一、import packages|导入第三方库 import pandas as pd import matplotlib.pyplot as plt impo…

利用ESP32实现蓝牙通信的方法

​大家好&#xff0c;我是ST! 上次给大家分享了如何使用ESP32实现UDP通信&#xff0c;今天跟大家聊聊如何使用ESP32实现蓝牙通信。 目录 一、蓝牙简介 二、miropython有关蓝牙的实现方法 三、我的实验代码 四、手机调试APP 一、蓝牙简介 蓝牙是一种无线通讯技术&#xff…

Linux篇【5】:Linux 进程概念(三)

目录 四、进程状态 4.1、各个操作系统下的进程状态&#xff1a; 4.1.1、进程的运行态&#xff1a; 4.1.2、进程的终止态(退出态)&#xff1a; 4.1.3、进程的阻塞态&#xff1a; 4.1.4、进程的挂起态&#xff1a; 4.2、Linux 操作系统下的进程状态&#xff1a; 四、进…

30、Java高级特性——Java API、枚举、包装类、装箱和拆箱

目录 课前先导&#xff1a; 一、Java API 1、API 2、Java API 3、Java API常用包 二、枚举类型 1、枚举 2、枚举类 3、代码演示 3.1 创建枚举类 3.2 创建测试类 4、MyEclipse创建枚举类的快捷方式 三、包装类 1、八大基本数据类型包装类 2、包装类中的构造方…

Java并发编程之可见性分析 volatile

可见性 对于什么是可见性&#xff0c;比较官方的解释就是&#xff1a;一个线程对共享变量的修改&#xff0c;另一个线程能够立刻看到。 说的直白些&#xff0c;就是两个线程共享一个变量&#xff0c;无论哪一个线程修改了这个变量&#xff0c;则另外的一个线程都能够看到上一…

电脑可以通过蓝牙发送文件吗?电脑蓝牙怎么发送文件

蓝牙&#xff08;bluetooth&#xff09;是一种支持设备短距离通信的无线电技术。能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换。蓝牙技术让数据传输变得更加迅速高效&#xff0c;为无线通信拓宽道路。随着蓝牙技术的发展&#xff0c;…

甘露糖-聚乙二醇-羧酸|mannose-PEG-COOH|羧酸-PEG-甘露糖

甘露糖-聚乙二醇-羧酸|mannose-PEG-COOH|羧酸-PEG-甘露糖 首先合成了二,三分支的甘露糖簇分子.甘露糖经烯丙 苷化,乙酰基保护后,将其烯丙基的双键氧化得到带有羧基连接臂的甘露糖衍生物,然后再分别与1,6-己二胺和三(2-氨乙基)胺进行缩合反应,后脱掉保 护基,得到二分枝甘露糖簇…

Azide-PEG-Thiol,N3-PEG-SH,叠氮-聚乙二醇-巯基可用来制备金纳米颗粒

1、名称 英文&#xff1a;Azide-PEG-Thiol&#xff0c;N3-PEG-SH 中文&#xff1a;叠氮-聚乙二醇-巯基 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a;Azide PEG Thiol PEG 4、分子量&#xff1a;可定制&#xff0c;5k N3-PEG-SH、20k 叠氮-聚乙二醇-巯基、10k N3-PE…

嵌入式分享合集105

一、智能灯光控制系统&#xff08;基于stm32&#xff09; 带你走进物联网的世界说一个整天方案哦 这次是基于stm32的 当然你可以用esp “智能光照灯”使用STM32作为系统的MCU&#xff0c;由于单片机IO口驱动电流过小&#xff0c;搭配三极管放大电流&#xff0c;从而满足光照强…

全网监控 nginx 部署 zabbix6.0

Zabbix监控 文章目录Zabbix监控一、zabbix6.0部署1、部署zabbix 6.0版本&#xff08;nginxphpzabbix&#xff09;1、nginx配置2、php配置3、mariadb配置二、zabbix配置1、zabbix配置 &#xff08;6.0&#xff09;1、源码安装2、zabbix rpm2、zabbix(5.0安装) -- 补充3、故障汇总…

【Linux】翻山越岭——进程地址空间

文章目录一、是什么写时拷贝二、为什么三、怎么做区域划分和调整一、是什么 回顾我们学习C/C时的地址空间&#xff1a; 有了这个基本框架&#xff0c;我们对于语言的学习更加易于理解&#xff0c;但是地址空间究竟是什么❓我们对其并不了解&#xff0c;是不是内存呢&#xff1…

【创建微服务】创建微服务并使用人人开源代码生成器生成基本代码

创建项目微服务 —— 添加模块 添加依赖 使用 人人开源代码生成器 快速生成 crud 代码 —— https://gitee.com/renrenio 下载导入人人开源项目后&#xff0c;修改 application.yml 文件下的数据库连接配置&#xff1a; 2. 修改 generator.properties 配置文件下的 主路径、包…

CC1101RGPR射频收发器 Low-Power Sub-1GHz 射频收发器

CC1101RGPR射频收发器 Low-Power Sub-1GHz 射频收发器 CC1101RGPR是一种低成本的 sub-1 GHz 收发器专为超低功耗无线应用而设计。该电路主要用于ISM&#xff08;工业、科学和医疗&#xff09;和SRD&#xff08;短程设备&#xff09;频段315、433、868 和 915 MHz&#xff0c;但…

【891. 子序列宽度之和】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。 给你一个整数数组 nums &#xff0c;返回 nums 的所有非空 子序列 的 宽度之和 。由于答案可能非常大&#xff0c;请返回对 109 7 取余 …

UNIAPP实战项目笔记40 设置和地址的页面布局

UNIAPP实战项目笔记40 设置和地址的页面布局 my-config.vue 设置页面布局 具体图片自己替换哈&#xff0c;随便找了个图片的做示例 代码 my-config.vue 页面部分 <template><view class"my-config"><view class"config-item" tap"go…

精益项目管理的流程

我们生活在一个企业家的世界&#xff0c;您可能有许多自己的想法等待实现&#xff0c;但想法在现实中实现是昂贵的。问题是您如何才能获得最大的收益&#xff1f;CEO和管理者如何在追逐梦想和实现目标的同时节省资金&#xff1f;了解初创公司如何进行精益项目管理&#xff0c;它…

第一个汇编程序

第一个汇编程序 文章目录第一个汇编程序1.汇编模拟程序&#xff1a;DOSBox使用2.汇编程序从写出到执行的过程3.程序执行过程跟踪1.汇编模拟程序&#xff1a;DOSBox使用 BOSBox软件常用基本语法&#xff1a; mount c: d:\masn ;挂载磁盘,挂载后用c:切换为C盘才能用debug等工具…

【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day09

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三明年实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…

uni-app入门:WXML列表渲染与条件渲染

1.列表渲染 1.1wx:for 1.2wx:key 2.条件渲染 2.1wx:if 2.2 hidden 正文 WXML全称&#xff1a;wexin markup language,微信标签语言&#xff0c;可以理解为web中的html&#xff0c;今天来讲一下列表渲染&#xff0c;通过几个小案例掌…