栈 | 队列

news2024/11/13 18:47:49

系统栈主要保存以下内容:

1.局部变量,2.函数的形参和返回值 3.函数的调用关系

一、栈

1.基本概念

栈是一种特殊的线性表,具有线性结构。表尾为栈顶,表头为栈顶。遵循先进后出原则,只能在栈顶进行插入和删除操作。

2.基本操作

栈的插入操作为入栈(进栈)。栈的删除操作为出栈。如下:

3.栈的顺序存储结构

     它使用一个一维数组来存储栈中的数据元素,数组的下标小的一端作为栈底,另一端作为栈顶。栈顶位置随入栈和出栈操作而变化,因此需要一个整型变量‌top来记录当前栈顶元素在数组中的位置。不多做介绍。

      分类:①满增栈     ②满减栈     ③空增栈     ④空减栈

基本类型类型说明出入栈操作
满增栈栈顶不为空,存储地址由低到高

入栈:栈顶++  入栈数据

出栈:出栈数据,栈顶--

满减栈栈顶不为空,存储地址由高到低

入栈:栈顶--  入栈数据

出栈:出栈数据,栈顶++

空增栈栈顶为空,存储地址由低到高

入栈:入栈数据,栈顶++

出栈:栈顶--,出栈数据

空减栈栈顶为空,存储地址由高到低

入栈:入栈数据,栈顶--

出栈:栈顶++,出栈数据

4.栈的链式存储结构

本质为单向链表。对于链栈来说,基本不存在栈满的情况。除非内存中已经没有可以使用的空间。

基本操作:

#include"link.h"
#include<stdio.h>
Stack_t *create_stack() //创建栈
{
	Stack_t*slink = malloc(sizeof(Stack_t));
	if(slink == NULL)
	{
		perror("fail malloc\n");
		return NULL;
	}
	slink->ptop = NULL;
	slink->clen = 0;
	return slink;
}
int is_empty_stack(Stack_t*slink)//判空
{
	return slink->ptop == NULL;
}
int push_stack(Stack_t*slink,Datatype data)//入栈
{
	Snode_t *pnode = malloc(sizeof(Snode_t));
    if(NULL == pnode)
    {
        perror("fail malloc\n");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;
    pnode->pnext = slink->ptop;
    slink->ptop = pnode;
    slink->clen++;
	return 0;
}
void stack_for_each(Stack_t*slink)//遍历打印
{
	Snode_t*p = slink->ptop;
	while(p )
	{
		printf("%d\n",p->data);
		p = p->pnext;
	}
	printf("\n");
}
int pop_stack(Stack_t*slink,Datatype * data)//出栈
{
	if (is_empty_stack(slink))
		return 0;

	Snode_t *pdel = slink->ptop;
	slink->ptop = pdel->pnext;
	if (data != NULL)
	{
		*data = pdel->data;
	}

	free(pdel);
	slink->clen--;

	return 1;
}
int get_stack_top(Stack_t*slink,Datatype *data)//获取栈顶的值
{
	if(is_empty_stack(slink))
	{
		return 0;
	}
	Snode_t*p = slink->ptop;
	*data = p->data;
	return 1;
}
void clear_stack(Stack_t*slink)//清空栈
{
	while(!is_empty_stack(slink))
	{
		pop_stack(slink,NULL);
	}
}	
void destroy_stack(Stack_t*slink)//销毁栈
{
	clear_stack(slink);
	free(slink);
}

栈的数据类型声明

typedef int Datatype;
typedef struct Snode
{
    Datatype data;
    struct Snode*pnext;
}Snode_t;
typedef struct Stack
{
    Snode_t*ptop;
    int clen;
}Stack_t;
extern Stack_t *create_stack();
extern int push_stack(Stack_t*slink,Datatype data);
extern int pop_stack(Stack_t*slink,Datatype * data);
extern int get_stack_top(Stack_t*slink,Datatype *data);
extern void clear_stack(Stack_t*slink);
extern void destroy_stack(Stack_t*slink);
extern void stack_for_each(Stack_t*slink);

5.循环栈与链队栈的比较

①在时间复杂度上是一样的,均为0(1)。

②空间性能,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,但它的优势是存取时定位很方便,而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制。所以它们的区别和线性表中讨论的一样,如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。

二、队列

1.概念

队列:允许从一端插入数据,另一端删除数据的线性存储结构(FIFO)

管道的本质也是队列,队列主要用于缓存数据

2.基本操作

插入操作为入队操作(队尾) 删除操作为出队操作(队头)

3.顺序队列

使用不当会出现存在假溢出现象,一般使用循环队列,充分利用循环空间。

4.链式队列

初始化:

typedef int QDataType;
typedef struct qnode
{
    QDataType data;
    struct qnode *pnext;
}QNode_t;
typedef struct queue
{
    QNode_t *pfront;
    QNode_t *prear;
    int clen;
    pthread_mutex_t mutex;
}Queue_t;

基本操作:

#include"link.h"
#include<stdio.h>
Queue_t*create_queue()
{
	Queue_t *qlink = malloc(sizeof(QNode_t));
	if(qlink == NULL)
	{
		perror("error malloc 1\n");
		return NULL;
	}
	qlink->pfront = NULL;
	qlink->prear = NULL;
	pthread_mutex_init(&(qlink->mutex),NULL);
	qlink->clen = 0;
	return qlink;
}
int is_empty_queue(Queue_t*qlink)
{
	if(NULL == qlink->pfront && qlink->prear == NULL)
	{
		return 1;
	}
	return 0;
}
int push_queue(Queue_t *qlink,QDataType data)
{
	QNode_t * pnode = malloc(sizeof(QNode_t));
	pnode->data = data;
	pnode->pnext = NULL;
	if(pnode == NULL)
	{
		perror("error malloc2\n");
		return -1;
	}
	if(is_empty_queue(qlink))
	{
		qlink->pfront = pnode;
		qlink->prear = pnode;
	}
	else
	{
		QNode_t * p = qlink->prear;
		p->pnext = pnode;
		qlink->prear = pnode;
		qlink->clen++;
	}
}
int pop_queue(Queue_t *qlink,QDataType  * data)
{
	QNode_t *del = qlink->pfront;
	if(is_empty_queue(qlink))
	{
		return -1;
	}
	if(qlink->clen == 1)
	{
		qlink->pfront = NULL;
		qlink->prear = NULL;
	}
	qlink->pfront = del->pnext;
	if(data != NULL)
	{
		*data = del->data;
	}
	free(del);
	qlink->clen--;
	return 1;
}
void print_for_each(Queue_t*qlink)
{
	QNode_t*p = qlink->pfront;
	while(p)
	{
		printf("%d\n",p->data);
		p = p->pnext;
	}
	printf("........................\n");
}
int get_queue_pop(Queue_t*qlink,QDataType *data)
{
	if(is_empty_queue(qlink))
	{
		return -1;
	}
	QNode_t*p = qlink->pfront;
	*data = p->data;
}
void clear_queue_pop(Queue_t*qlink)
{
	while(!is_empty_queue(qlink))
	{
		pop_queue(qlink,NULL);
	}
}
void destroy_queue(Queue_t*qlink)
{
	clear_queue_pop(qlink);
	free(qlink);
}

5.循环队列与链队列的比较

①从时间上,其实它们的基本操作都是常数时间,即都为0(1)的,不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则两者还是有细微差异。

②空间上来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链队列更加灵活。

三、问答。

1.程序运行过程中的栈区和数据结构的栈有什么区别?

程序运行过程中的栈区和数据结构中的栈是两个不同的概念,它们分别属于内存管理和数据结构领域。

  • 数据结构中的栈‌是一种后进先出(LIFO)的数据结构,它只允许在栈顶进行数据的添加(压栈)或移除(出栈)操作。数据结构中的栈是一种抽象数据类型,用于管理数据的存储和访问方式,它不直接涉及物理内存的分配和管理‌。

  • 程序运行过程中的栈区‌则是指内存中的一个特定区域,用于存储局部变量、函数调用的上下文信息等。在程序运行时,操作系统或运行时环境会自动管理这部分内存的分配和释放。栈区的特点是快速分配和释放内存,但空间大小通常受到限制,且只能从栈顶进行操作‌。

简而言之,数据结构中的栈是一种抽象数据类型,用于组织和管理数据;而程序运行过程中的栈区是内存中的一个具体区域,用于存储程序执行时的临时数据和函数调用信息,这两者在计算机科学中各有其用途和重要性‌。

2.队列和栈有什么区别?

①规则不同

1. 队列:先进先出(First In First Out)FIFO

2. 栈:先进后出(First In Last Out )FILO

②对插入和删除操作的限定不同

1. 队列:只能在表的一端进行插入,并在表的另一端进行删除;

2. 栈:只能在表的一端插入和删除。

③遍历数据速度不同

1. 队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;

2. 栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。

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

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

相关文章

KADAL | Kriging代理模型Python工具箱推荐

用于分析、设计优化和探索的Kriging工具箱 简介Required packagesQuick ExamplesContact特别感谢&#xff1a;参考资料 简介 用于分析、设计优化和探索的克里金法 (Kriging for Analysis, Design optimization, And expLoration, KADAL) 是由万隆理工学院 (Institut Teknologi…

Linux——解压大型zip文件报错:bad zipfile offset (local header sig) 的解决方法

一、现象描述 完整一行报错信息&#xff1a; error: invalid compressed data to inflate file #14: bad zipfile offset (local header sig) 二、解决办法 利用 -F 去修复&#xff1a; zip -F xxx.zip --out large.zip得到&#xff1a; 解压&#xff1a; unzip large.zi…

COI实验室技能:图像到图像的深度学习开发框架(pytorch版)

Basic deep learning framework for image-to-image 这个开发框架旨在帮助科研人员快速地实现图像到图像之间的模型开发。 github连接&#xff1a;https://github.com/SituLab/Basic-deep-learning-framework-for-image-to-image 目录 1模型开发 1-1克隆项目到本地1-2深度学…

HashMap实现原理分析

for (Entry<K,V> e table[i]; e ! null; e e.next) { Object k; //如果key在链表中已存在&#xff0c;则替换为新value if (e.hash hash && ((k e.key) key || key.equals(k))) { V oldValue e.value; e.value value; e.recordAccess(this); retur…

今麦郎「日记薪·1号发」 即时反馈,激活10000+名基层员工

本文内容整理自红海云CEO孙伟对今麦郎集团人力资源总经理王高峰、IT管理中心副总经理邹大勇的访谈。 坚持创新求变的品牌基因 过去30年&#xff0c;中国食品工业蓬勃发展&#xff0c;孕育出一批批在国际舞台上熠熠生辉的民族品牌。今麦郎作为民族品牌代表&#xff0c;自1994年…

FreeRTOS学习笔记—④RTOS通信管理篇/同步互斥与通信(正在更新中)

二、RTOS的核心功能 RTOS的核心功能块主要分为任务管理、内核管理、时间管理以及通信管理4部分&#xff0c;框架图如下所示&#xff1a;   &#xff08;1&#xff09;任务管理&#xff1a;负责管理和调度任务的执行&#xff0c;确保系统中的任务能够按照预期运行。   &…

信息学奥赛初赛天天练-84-NOIP2014普及组-基础题3-总线、存储器、邮件协议、二叉树、满二叉树、顶点的度、无向图、有向图

信息学奥赛初赛天天练-84-NOIP2014普及组-基础题3-总线、存储器、邮件协议、二叉树、满二叉树、顶点的度、无向图、有向图 PDF文档公众号回复关键字:20240906 1 NOIP 2014 普及组 基础题3 6 CPU、存储器、I/O 设备是通过( )连接起来的 A 接口 B 总线 C 控制线 D 系统文件 7 …

集成电路学习:什么是ROM只读存储器

ROM&#xff1a;只读存储器 ROM&#xff08;Read-Only Memory&#xff0c;只读存储器&#xff09;是一种重要的计算机存储设备&#xff0c;具有独特的特点和应用场景。以下是对ROM的详细解析&#xff1a; 一、ROM的定义与特点 ROM是一种只能读出事先所存数据的固态半导体存储器…

【系统架构设计师-2021年】综合知识-答案及详解

文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6~7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第21题】【第22题】【第23题】【第24题】【第25题】【第26题】【第…

计算机基础知识-2

AT&T汇编和Intel汇编的区别 每取出完一条指令&#xff0c;PC会自动&#xff0b;"1"&#xff0c;指向下一条要被执行的指令。这里的1是指下一条指令&#xff0c;但是指令本身可能占用多个字节&#xff0c;所以地址可能不是以1叠加 当前执行的是108地址的指令&…

APS开源源码解读: 排程工具 optaplanner

抽象层次非常好&#xff0c;广义优化工具。用于排产没有复杂的落地示例 https://github.com/apache/incubator-kie-optaplanner/blob/main/optaplanner-examples/src/main/java/org/optaplanner/examples/projectjobscheduling/app/ProjectJobSchedulingApp.javahttps://github…

亿佰特-NT1/NT1-B串口转RJ45以太网模块

亿佰特-NT1/NT1-B串口转RJ45以太网模块 模块概要连接方式配置模块亿佰特网络配置助手配置模块网页版配置模块 串口以太网双向数据收发AT模式配置模块 模块概要 亿佰特官网 https://www.ebyte.com/ 模块概要&#xff1a; 接口方式&#xff1a;TTL串口RJ45工作电压&#xff1a…

黑神话悟空红孩儿怎么打 妖王红孩儿攻略

​在《黑神话悟空》中&#xff0c;红孩儿作为IP里的经典BOSS&#xff0c;是一位相当顽皮的BOSS。接下来小编给大家带来了黑神话悟空红孩儿怎么打的攻略&#xff0c;一起来看看吧。 一、BOSS位置 随着主线流程的推进自然解锁。 二、BOSS打法 1、优先强化【身外身法】与【变身…

算法训练营——day3长度最小子数组

1 长度最小子数组-力扣209&#xff08;中等&#xff09; 1.1 题目&#xff1a; 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返…

springboot+vue+mybatis计算机毕业设计积分商城管理系统+PPT+论文+讲解+售后

近年来互联网络的迅猛发展和电子终端设备的普及&#xff0c;赋予了各行业充足的发展空间。积分商城管理系统相比于传统信息技术&#xff0c;时效性是它最大的特色&#xff0c;已经在电子娱乐、经济等中发挥着举足轻重的作用。2019年疫情的爆发&#xff0c;更是短时间内迅速扩大…

Spring之Bean的生命周期 2024-9-6 19:47

目录 什么是Bean的生命周期为什么要知道Bean的生命周期Bean的生命周期之5步Bean生命周期之7步Bean生命周期之10步 声明&#xff1a;本章博客内容采自老杜2022spring6 语雀文档 什么是Bean的生命周期 Spring其实就是一个管理Bean对象的工厂。它负责对象的创建&#xff0c;对象的…

据说这是一个能让AI自动升级的超级提示词,我试一试效果咋样

本文背景 前阵子我在某个地方看到个超离谱的 Prompt&#xff0c;把我和几百万网友都给整懵了。 说真的&#xff0c;好久没见过这么抽象的 Prompt 了。 这玩意儿在那地方火得不行&#xff0c;才发没两天就有一百多万浏览量。 还有个只有两个 Markdown 文件的 GitHub 项目&#x…

python中 if __name__ == “__main__“的代码没被执行

运行pytest 和unittest时&#xff0c;if name “main”: 下的代码没有被执行&#xff0c;发现__name__等于模块名 一、“name” 的作用 1、 __name__是python的一个内置类属性&#xff0c;它天生就存在于一个 python 程序中。 2、直接运行python程序时&#xff0c;__name__的…

Elastic Stack--ES集群加密及Kibana的RBAC实战

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

基于Java+SpringBoot+Vue+MySQL的社区医疗服务管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的可视化社区医疗服务管理系统【附源码文…