栈和队列的实现

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)

相关推荐
古希腊掌管学习的神26 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师27 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程35 分钟前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
每天都要学信号1 小时前
Python(第一天)
开发语言·python
TENET信条1 小时前
day53 第十一章:图论part04
开发语言·c#·图论
生信圆桌1 小时前
【生信圆桌x教程系列】如何安装 seurat V5版本R包,最详细安装手册
开发语言·r语言
IT猿手1 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解TP1-TP10及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·深度学习·算法·机器学习·matlab·多目标算法
单片机学习之路2 小时前
【C语言】结构
c语言·开发语言·stm32·单片机·51单片机