【数据结构】栈和队列的实现

发布于:2025-07-27 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

1 栈的概念和结构

2 栈的实现 

2.1 Stack.h文件

2.2 Stack.c文件

2.3 test.c文件

3 队列的概念及结构 

4 队列的实现 

4.1 Queue.h文件

4.2 Queue.c文件

4.3 test.c文件 


1 栈的概念和结构

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

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

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

2 栈的实现 

栈的实现一般可以用数组或者链表实现,相对而言数组的实现更优一些。数组在尾上插入数据的代价比较小。本文采用数组实现的方法。

 栈的实现需要创建一个头文件Stack.h,一个源文件Stack.c和一个测试文件test.c,用来测试功能。

2.1 Stack.h文件

#pragma once

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;
	int top;//指向栈顶元素的下一个位置
	int capacity;//容量
}ST;

//栈的初始化
void STInit(ST* pst);
//插入数据(入栈)
void STPush(ST* pst, STDataType x);
//删除数据(出栈)
void STPop(ST* pst);
//获取栈顶数据
STDataType STTop(ST* pst);
//判断栈是否为空
bool STEmpty(ST* pst);
//获取栈里的数据个数
int STSize(ST* pst);
//栈的销毁
void STDestroy(ST* pst);

2.2 Stack.c文件

#include "Stack.h"
//栈的初始化
void STInit(ST* pst)
{
	pst->arr = NULL;
	pst->capacity = 0;
	pst->top = 0;
}
//插入数据(入栈)
void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//判断空间是否足够,不够就扩容
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;
		STDataType* tmp = (STDataType*)realloc(pst->arr, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		pst->capacity = newcapacity;
		pst->arr = tmp;
	}
	//插入数据
	pst->arr[pst->top] = x;
	pst->top++;
}
//删除数据(出栈)
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}
//获取栈顶数据
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	return pst->arr[pst->top - 1];
}
//判断栈是否为空
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}
//获取栈里的数据个数
int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}
//栈的销毁
void STDestroy(ST* pst)
{
	free(pst->arr);
	pst->arr = NULL;
	pst->top = 0;
	pst->capacity = 0;
}

2.3 test.c文件

#include "Stack.h"
int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	while (!STEmpty(&s))
	{
		printf("%d\n", STTop(&s));
		STPop(&s);
	}
	//printf("%d\n", STTop(&s));
	//STPop(&s);
	STDestroy(&s);
	return 0;
}

3 队列的概念及结构 

队列只允许在一端插入数据,在另一端进行删除数据操作的特殊线性表。队列中的数据元素遵循先进先出的原则。插入数据的一端称为队尾,进行删除操作的一端称为队头

4 队列的实现 

队列可以用数组和链表的结构实现,使用链表的结构实现更好一些,如果使用数组的结构,出队列在数组头上出数据,效率比较低。本文采用链表的结构实现。

实现队列需要创建一个头文件Queue.h,源文件Queue.c,测试文件test.c,用来测试功能。

4.1 Queue.h文件

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

typedef int QDataType;

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


typedef struct Queue
{
	QNode* phead;//头指针
	QNode* ptail;//尾指针
	int size;//队列内数据个数
}Queue;

//初始化
void QueueInit(Queue* pq);
//插入数据(队尾)
void QueuePush(Queue* pq, QDataType x);
//删除数据(队头)
void QueuePop(Queue* pq);
//取出队头数据
QDataType QueueFront(Queue* pq);
//取出队尾数据
QDataType QueueBack(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//统计队列数据个数
int QueueSize(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);

4.2 Queue.c文件

#include "Queue.h"
//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
//插入数据(队尾)
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(1);
	}
	newnode->next = NULL;
	newnode->val = x;
	if (pq->ptail==NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;
}
//删除数据(队头)
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size != 0);
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = NULL;
		pq->ptail = NULL;
	}
	else
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}
//取出队头数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}
//取出队尾数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->ptail);
	return pq->ptail->val;
}
//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}
//销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}
//统计队列数据个数
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

4.3 test.c文件 

#include "Queue.h"
int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return 0;
}

 以上就是栈和队列的结构和代码实现,是依据顺序表和链表的原理来实现栈和队列,感兴趣的可以查看我之前的顺序表和链表的文章,如果这篇文章对你有用,可以点点赞哦,你的支持就是我写下去的动力,后续会不断地分享知识。


网站公告

今日签到

点亮在社区的每一天
去签到