当前位置: 首页 > article >正文

数据结构---线性表--栈和队列

1.栈

1.1栈的概念

栈,一种特殊的线性表,其只允许在固定的一端进行插入和删除元素,进行数据插入和删除的一端叫做栈顶,另一端叫做栈底。栈中的数据元素必须遵守后进先出LIFO(Last In First Out )的原则。

压栈:栈的插入操作称为进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作称为出栈,出数据也在栈顶

头插头删

1.2栈的结构

1.3栈的实现

栈的实现一般可以用数组或者链表实现,数组的长度是固定的,但是可以使用malloc/realloc开辟空间;数组的元素是连续的(带有下标),使得索引操作更快,入栈出栈更方便。链表的维护与数组不同,链表通过指针维护,这导致链表的随机访问不如数组,因为需要遍历节点,并且链表的每个节点需要额外的指针,增加了内存的开销。因此一般使用数组实现栈。

 接口:

typedef int SdataType;

typedef struct Stack
{
	SdataType* a;
	int top;
	int capacity;
}ST;
//初始化
void StackInit(ST* pst);
//入栈
void StackPush(ST* pst,SdataType x);
//出栈
void StackPop(ST* pst);
//获取栈顶元素
SdataType StackTop(ST* pst);
//获取栈中有效数据个数
int StackSize(ST* pst);
//检查栈是否为空
bool StcakEmpty(ST* pst);
//销毁栈
void StackDestroy(ST* pst);
//初始化
void StackInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}
//入栈
void StackPush(ST* pst, SdataType x)
{
	assert(pst);
	if (pst->capacity == pst->top)
	{
		int new_capacity = pst->capacity == 0 ? 4 : 2*pst->capacity;
        //tmp为空时,realloc起malloc的作用
		SdataType *tmp = (SdataType*)realloc(pst->a, new_capacity*sizeof(SdataType));
		if (tmp == NULL)
		{
			perror("malloc filed:");
			exit(1);
		}
		pst->capacity = new_capacity;
		pst->a = tmp;
	}
	pst->a[pst->top++] = x;
}
//出栈
void StackPop(ST* pst)
{
	assert(pst && pst->top > 0);
	pst->top--;
}
//获取栈顶元素
SdataType StackTop(ST* pst)
{
	assert(pst && pst->top>0);
	return pst->a[pst->top-1];
}

//获取栈中有效数据个数
int StackSize(ST* pst)
{
	assert(pst && pst->top > 0);
	return pst->top;
}
//检查栈是否为空  空->1  非空->0
bool StcakEmpty(ST* pst)
{
	assert(pst);
	return(pst->top==0);
}
//销毁栈
void StackDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->top = pst->capacity = 0;
}

2.队列

2.1队列的概念

队列,也是一种特殊的线性表,只允许在一端进行插入数据操作,在另一端进行删除数据操作,队列具有先进先出FIFO(First In First Out)的特点。进行插入操作的一端称为队尾,进行删除的一端称为对头。

2.2队列的结构

队列也可以用数组或链表实现,数组是连续的空间,当我们对数组进行删除的时候,数组的空间不会自动释放或者补上,这就会导致不管让数组从后往前还是从前往后存储队列都会出现前面的空间浪费的问题(循环数组除外)。使用链表就可以很好的解决这个问题,链表的空间都是独立申请的,删除之后可以回收,就可以让后面的节点补上,不会造成空间浪费。(在插入的时候,链表也优于数组)因此一般链表的实现采用链表。 

 2.2队列的实现

接口:

typedef int QDataType;

typedef struct QueueNode
{
	QDataType* val;
	struct Queue* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	size_t size;
}Queue;

//初始化队列
void QueueInit(Queue* qs);
//队尾入队列
void QueuePush(Queue*qs, QDataType x);
//队头出队列
void QueuePop(Queue* qs);
//获取队列队头元素
QDataType QueueFront(Queue* qs);
//获取队列队尾元素
QDataType QueueBack(Queue* qs);
//获取队列有效元素个数
size_t QueueSize(Queue* qs);
//检测队列是否为空  空-->!0  非空-->0
int QueueEmpty(Queue* qs);
//销毁队列
void QueueDestroy(Queue* qs);
//初始化队列
void QueueInit(Queue* qs)
{
	assert(qs);
	qs->phead = qs->ptail = NULL;
	qs->size = 0;
}
//队尾入队列-->尾插
void QueuePush(Queue* qs, QDataType x)
{
	assert(qs);
	QueueNode* new_node = (QueueNode*)malloc(sizeof(QueueNode));
	if (new_node == NULL)
	{
		perror("malloc failed:");
		exit(1);
	}
	new_node->next = NULL;
	new_node->val = x;
	//插入空节点的队列
	if (qs->ptail==NULL)
	{
		qs->phead = qs->ptail = new_node;
	}
	//插入有节点的队列
	else
	{
		qs->ptail->next = new_node;
		qs->ptail = new_node;
	}
	++qs->size;
}
//队头出队列
void QueuePop(Queue* qs)
{
	assert(qs && qs->size>0);
	//一个节点
	if (qs->phead->next==NULL)
	{
		free(qs->phead);
		qs->phead = qs->ptail = NULL;
	}
	//多个节点
	else
	{
		QueueNode* next = qs->phead->next;
		free(qs->phead);
		qs->phead = next;
	}

	--qs->size;
}
//获取队列队头元素
QDataType QueueFront(Queue* qs)
{
	assert(qs && qs->size > 0);
	return qs->phead->val;
}
//获取队列队尾元素
QDataType QueueBack(Queue* qs)
{
	assert(qs && qs->size > 0);
	return qs->ptail->val;
}
//获取队列有效元素个数
size_t QueueSize(Queue* qs)
{
	return qs->size;
}
//检测队列是否为空  空-->!0  非空-->0
int QueueEmpty(Queue* qs)
{
	return (qs->size == 0);
}
//销毁队列
void QueueDestroy(Queue* qs)
{
	assert(qs);
	QueueNode* pcur = qs->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	qs->phead = qs->ptail = NULL;
	qs->size = 0;
}

http://www.kler.cn/a/288650.html

相关文章:

  • JVM 中的完整 GC 流程
  • 服务器显卡和桌面pc显卡有什么不同
  • 深度学习之卷积问题
  • OpenGL ES 共享上下文实现多线程渲染
  • uni-app移动端与PC端兼容预览PDF文件
  • 【QT】QSS
  • ActiveMQ实战指南:实现发布/订阅(publish-subscribe)消息发送!
  • Unity Android 进阶之 【Android 添加一个启动动画】在Unity场景加载完之前,避免 【Unity 启动界面慢 黑屏时间长】的情况
  • 青远生态为云南林业规划院定制开发的自然保护地规划智能编制系统顺利通过验收
  • Golang | Leetcode Golang题解之第385题迷你语法分析器
  • Java图形用户界面之Applet设计
  • python django 使用教程
  • 使用 streamlink 把 m3u8 转为 mp4
  • 代码随想录 刷题记录-24 图论 (1)理论基础 、深搜与广搜
  • 保姆级Maven安装、配置、版本查询教程(包含配置本地仓库、阿里云私服、环境变量)
  • 射频指纹特征提取:揭秘无线通信设备的身份标识
  • 网络准入管理系统是什么?网络准入很重要,2024年国内外网络准入控制系统有哪些?(靠谱儿~)
  • filezilla使用教程(window下filezilla使用教程)
  • TF | SD 卡出现无法删除的文件,乱码文件该如何处理 macOS
  • 太速科技-基于Kintex-7 XC7K160T 的CameraLink转四路光纤数据转发卡(Full Camera Link图像转万兆以太网适配器 )
  • PostgreSQL + PostGIS:空间数据存储及管理解决方案
  • 【java入门】JDK的下载安装与配置,最新最详细教程!
  • vue3+vite+ts如何使用路由
  • pyecharts可视化数据大屏
  • 【Python】3.基础语法(3)函数
  • Python实现BASE64 算法