栈和队列详解

1.栈

1.1概念与结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中元素遵循先进后出的原则。

**压栈:**栈的插入操作叫做进站/压栈/入栈,入数据在栈顶。

出栈: 栈的删除操作叫做出栈。出数据也在栈顶。

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

1.2栈的实现

stack.h

cpp 复制代码
#pragma once
#include"stdio.h"
#include"stdio.h"
#include"assert.h"
#include<stdbool.h>

//定义栈的结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;
	int capacity;     //栈的空间大小
	int top;          //栈顶
}ST;

//初始化
void STInit(ST* ps);
//释放空间
void STDestroy(ST* ps);

//栈顶---入数据、出数据
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);

//取栈顶元素
STDataType StackTop(ST* ps);

//栈是否为空
bool StackEmpty(ST* ps);

//获取栈中有效元素个数
int STSize(ST* ps);

1.初始栈

cpp 复制代码
void STInit(ST* ps)
{
	asssert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

2.销毁栈

cpp 复制代码
void STDestroy(ST* ps)
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

3.入栈

cpp 复制代码
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//判断空间是否充足
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity = 0 ? 4 : 2 * ps->capacity;
		STDataType* tmp = (STDataType*)realloc(ps->capacity, newcapacity * sizeof(newcapacity));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
	ps->arr[ps->top] = x;
	ps->top++;
}

4.判断栈是否为空

cpp 复制代码
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

5.出栈

cpp 复制代码
void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	--ps->top;
}

6.取栈顶元素

cpp 复制代码
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

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

7.获取栈中有效元素个数

cpp 复制代码
int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

2.队列

2.1概念与结构

概念:只允许在一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列具有先进先出的原则。

**入队列:**进行插入操作的一端称为队尾。

**出队列:**进行删除操作的一端称为队头。

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

2.2队列的实现

queue.h

cpp 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//定义队列结构
typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;//保存队列有效数据个数
}Queue;

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

// ⼊队列,队尾
void QueuePush(Queue* pq, QDataType x);
// 出队列,队头
void QueuePop(Queue* pq);

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

//取队头数据
QDataType QueueFront(Queue* pq);

//取队尾数据
QDataType QueueBack(Queue* pq);

//队列有效元素个数
int QueueSize(Queue* pq);

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

1.队列初始化

cpp 复制代码
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

2.从队尾入队列

cpp 复制代码
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->phead = NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;
}

3.队列判空

cpp 复制代码
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL && pq->ptail == NULL;
}

4.从队头出队列

cpp 复制代码
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->ptail == pq->phead)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	--pq->size;
}

5.取队头数据

cpp 复制代码
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->phead->data;
}

6.取队尾数据

cpp 复制代码
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->ptail->data;
}

7.队列有效元素个数

cpp 复制代码
int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

8.销毁队列

cpp 复制代码
void QueueDestroy(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}
相关推荐
Coder_Boy_3 分钟前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
helloworldandy11 分钟前
使用Pandas进行数据分析:从数据清洗到可视化
jvm·数据库·python
DuHz13 分钟前
超宽带脉冲无线电(Ultra Wideband Impulse Radio, UWB)简介
论文阅读·算法·汽车·信息与通信·信号处理
Polaris北极星少女34 分钟前
TRSV优化2
算法
代码游侠1 小时前
C语言核心概念复习——网络协议与TCP/IP
linux·运维·服务器·网络·算法
2301_763472462 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
数据知道2 小时前
PostgreSQL 故障排查:如何找出数据库中最耗时的 SQL 语句
数据库·sql·postgresql
qq_12498707532 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
枷锁—sha2 小时前
【SRC】SQL注入WAF 绕过应对策略(二)
网络·数据库·python·sql·安全·网络安全
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端