栈和队列的实现

1.栈

1.1栈的概念及结构

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

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

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

1.2栈的实现

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

Stack.h

复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDateType;

typedef struct stack
{
	STDateType* a;
	int top;
	int capacity;
}stack;

void STInit(stack* pst);//初始化

void STDestory(stack* pst);//销毁

void STPush(stack* pst, STDateType x);//入栈

void STPop(stack* pst);//出栈

STDateType STTop(stack* pst);//取栈顶元素

bool STEmpty(stack* pst);//判空

int STSize(stack* pst);//获取元素个数

stack.c

复制代码
#include"stack.h"

void STInit(stack* pst)//初始化
{
	assert(pst);

	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

void STDestory(stack* pst)//销毁
{
	assert(pst);

	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}

void STPush(stack* pst, STDateType x)//入栈
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDateType* tmp = (STDateType*)realloc(pst->a,(newcapacity *sizeof(STDateType)));
		
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top++] = x;

}

void STPop(stack* pst)//出栈
{
	assert(pst);
	assert(pst->top > 0);

	pst->top--;
}

STDateType STTop(stack* pst)//取栈顶元素
{
	assert(pst);
	assert(pst->top > 0);

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

bool STEmpty(stack* pst)//判空
{
	assert(pst);
	return pst->top == 0;
}

int STSize(stack* pst)//获取元素个数
{
	assert(pst);
	return pst->top;
}

test.c

复制代码
#include"stack.h"

int main()
{
	stack st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	while (!STEmpty(&st))
	{
		printf("%d\n", STTop(&st));
		STPop(&st);
	}
	STDestory(&st);
}

2.队列

2.1队列的概念和结构

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

2.2队列的实现

queue.h

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

typedef int QDataType;

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

typedef struct Queue
{
	QueueNode* qhead;
	QueueNode* qtail;
	int size;
}Queue;

void QInit(Queue* pq);//初始化

void QDestory(Queue* pq);//销毁

void QPush(Queue* pq, QDataType x);//入队列

void QPop(Queue* pq);//出队列

bool QEmpty(Queue* pq);//判空

int QSize(Queue* pq);//队列元素个数

QDataType QueueFront(Queue* pq);//队列头元素

QDataType QueueBack(Queue* pq);//队列尾元素

queue.c

复制代码
#include"queue.h"

void QInit(Queue* pq)//初始化
{
	assert(pq);
	
	pq->qhead = pq->qtail = NULL;
	pq->size = 0;
}

void QDestory(Queue* pq)//销毁
{
	QueueNode* cur = pq->qhead;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->qhead = pq->qtail = NULL;
	pq->size = 0;
}

void QPush(Queue* pq, QDataType x)//入队列
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->next = NULL;
	newnode->val = x;
	if (pq->qtail == NULL)
	{
		pq->qhead = pq->qtail = newnode;
	}
	else
	{
		pq->qtail->next = newnode;
		pq->qtail = newnode;
	}
	pq->size++;
}

void QPop(Queue* pq)//出队列
{
	assert(pq);
	assert(pq->qhead);

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

bool QEmpty(Queue* pq)//判空
{
	assert(pq);
	return pq->size == 0;
}

int QSize(Queue* pq)//队列元素个数
{
	assert(pq);

	return pq->size;
}

QDataType QueueFront(Queue* pq)//队列头元素
{
	assert(pq);
	assert(pq->qhead);

	return pq->qhead->val;
}

QDataType QueueBack(Queue* pq)//队列尾元素
{
	assert(pq);
	assert(pq->qtail);

	return pq->qtail->val;
}

test.c

复制代码
int main()
{
	Queue pq;
	QInit(&pq);
	QPush(&pq, 1);
	QPush(&pq, 2);
	QPush(&pq, 3);
	QPush(&pq, 4);

	printf("%d ", QueueFront(&pq));
	QPop(&pq);
	printf("%d ", QueueFront(&pq));
	QPop(&pq);
	QPop(&pq);
	printf("%d ", QueueBack(&pq));
	QPop(&pq);
	return 0;
}

3.栈和队列的面试题

20. 有效的括号 - 力扣(LeetCode)

225. 用队列实现栈 - 力扣(LeetCode)

232. 用栈实现队列 - 力扣(LeetCode)

622. 设计循环队列 - 力扣(LeetCode)

相关推荐
RS迷途小书童1 分钟前
Python 解析大疆无人机 SRT 字幕日志
开发语言·python·无人机
我不会起名字32211 分钟前
一天一道算法题(29):单调栈
java·数据结构·python·算法·leetcode·golang·单调栈
点心的游戏开发世界28 分钟前
GDScript 入门笔记(十六):文件读写与数据持久化
开发语言·笔记·游戏引擎·godot
苦瓜小生32 分钟前
【前端】【力扣与手撕】十天带你刷完前端算法与手撕,全是最简单好记的最优解法!day4
前端·数据结构·算法·leetcode·面试
会飞的拖把36 分钟前
Python序列详解:列表、元组、字符串的通用操作(超详细版)
开发语言·windows·python
reasonsummer1 小时前
【办公类-115-01】20260906育儿知识(家园小报)批量制作(2026年9月-2027年6月)
开发语言·数据库·c#
君顾11 小时前
智慧场馆解决方案小程序系统实战:从架构设计到上线指南
java·开发语言·智慧场馆
zhougl9961 小时前
Dockerfile实战教程
java·开发语言·spring boot
FfHUCisI1 小时前
Golang 网络轮询器 netpoll:把阻塞 IO 变成事件通知
开发语言·网络·golang
XiaoQiao6669991 小时前
C 语言常用头文件及里面核心函数
c语言·开发语言