栈和队列的实现

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)

相关推荐
im_AMBER8 分钟前
Leetcode 47
数据结构·c++·笔记·学习·算法·leetcode
我命由我1234512 分钟前
Java 并发编程 - Delay(Delayed 概述、Delayed 实现、Delayed 使用、Delay 缓存实现、Delayed 延迟获取数据实现)
java·开发语言·后端·缓存·java-ee·intellij-idea·intellij idea
HLJ洛神千羽12 分钟前
C++程序设计实验(黑龙江大学)
开发语言·c++·软件工程
kyle~18 分钟前
算法数学---差分数组(Difference Array)
java·开发语言·算法
曹牧18 分钟前
C#:三元运算符
开发语言·c#
Jonathan Star36 分钟前
MediaPipe 在Python中实现人体运动识别,最常用且高效的方案是结合**姿态估计**(提取人体关键点)和**动作分类**(识别具体运动)
开发语言·python·分类
滨HI01 小时前
C++ opencv拟合直线
开发语言·c++·opencv
沐浴露z1 小时前
详解JDK21新特性【虚拟线程】
java·开发语言·jvm
艾莉丝努力练剑1 小时前
【C++:红黑树】深入理解红黑树的平衡之道:从原理、变色、旋转到完整实现代码
大数据·开发语言·c++·人工智能·红黑树
l1t1 小时前
利用DeepSeek优化SQLite求解数独SQL用于DuckDB
开发语言·数据库·sql·sqlite·duckdb