数据结构--栈和队列(及其实现)

一.栈的介绍

1.栈的定义

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

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

出栈:栈的删除操作叫做出栈。出数据也在栈顶。
在这里插入图片描述

2.压栈和出栈结构示意图

数组形式:
在这里插入图片描述
链式结构:
在这里插入图片描述

据图可知,二者的操作都是在top处进行

3.栈的实现(推荐使用数组)

(1)Stack.h 栈的管理及接口

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack
{
    
    
	STDataType* a;//动态数组
	int top;  //栈顶
	int capacity;  //容量
}Stack;
//初始化栈
void StackInit(Stack* pst);
//销毁栈
void StackDestroy(Stack* pst);
//入栈
void StackPush(Stack* pst, STDataType data);
//出栈
void StackPop(Stack* pst);
//获取栈中有效元素的个数
int StackSize(Stack* pst);
//获取栈顶元素
STDataType StackTop(Stack* pst);
//检测栈是否为空,为空返回1,非空返回0
int StackEmpty(Stack* pst);

(2)Stack.c 栈各个接口功能的实现

#include"Stack.h"
//初始化栈
void StackInit(Stack* pst)
{
    
    
	assert(pst);
	pst->a = (STDataType*)malloc(sizeof(STDataType)* 4);
	if (pst->a == NULL)
	{
    
    
		printf("malloc fail");
	}
	pst->top = 0;
	pst->capacity = 4;
}
//销毁栈
void StackDestroy(Stack* pst)
{
    
    
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = 0;
	pst->capacity = 0;
}
//入栈
void StackPush(Stack* pst, STDataType data)
{
    
    
	assert(pst);
	//空间不够需要增容
	if (pst->top == pst->capacity)
	{
    
    
		//增容为原来的2倍
		int* tem = (STDataType*)realloc(pst->a, sizeof(STDataType)* pst->capacity * 2);
		if (tem == NULL)
		{
    
    
			printf("realloc fail");
			exit(-1);
		}
		pst->a = tem;
		pst->capacity = pst->capacity * 2;
	}
	pst->a[pst->top] = data;
	pst->top++;
}
//出栈
void StackPop(Stack* pst)
{
    
    
	assert(pst);
	//判断栈是否为空
	//相当于assert(pst->top != 0);
	assert(!StackEmpty(pst));
	pst->top--;
}
//获取栈中有效元素的个数
int StackSize(Stack* pst)
{
    
    
	assert(pst);
	//因为初始化top是0,如果初始化top是-1则返回top+1;
	return pst->top;
}
//获取栈顶元素
STDataType StackTop(Stack* pst)
{
    
    
	assert(pst);
	assert(!StackEmpty(pst));
	return pst->a[pst->top - 1];
}
//检测栈是否为空,为空返回1,非空返回0
int StackEmpty(Stack* pst)
{
    
    
	assert(pst);
	return pst->top == 0 ? 1 : 0;
}

(3)test.c测试

#include"Stack.h"
void test()
{
    
    
	//定义一个栈
	Stack st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
    
    
		//取一个删一个
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	StackDestroy(&st);
	printf("\n");
}
int main()
{
    
    
	test();
	return 0;
}

在这里插入图片描述

二.队列的介绍

1.队列的定义

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列遵守先进先出FIFO(First In First Out)的原则

入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
在这里插入图片描述

2.队列的实现(推荐使用链表)

(1)Queue.h 队列的管理及接口

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef int QDatatype;
//链式结构:表示队列
typedef struct QueueNode
{
    
    
	QDatatype data;
	//指向下一个节点的指针
	struct QueueNode* next;
}QueueNode;

//队列的结构
typedef struct Queue
{
    
    
	QueueNode* front;//头指针
	QueueNode* tail;//尾指针
}Queue;
//初始化队列
void QueueInit(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);
//队尾入队列
void QueuePush(Queue* pq, QDatatype x);
//队头出队列
void QueuePop(Queue* pq);
//检测队列是否为空,为空返回1,非空返回0
int QueueEmpty(Queue* pq);
//获取队列中有效元素的个数
int QueueSize(Queue* pq);
//获取队列头部元素
QDatatype QueueFront(Queue* pq);
//获取队列队尾元素
QDatatype QueueBack(Queue* pq);

(2)Queue.c 队列各个接口功能的实现

#include"Queue.h"
//初始化队列
void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->front = pq->tail = NULL;
}
//销毁队列
void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	QueueNode* cur = pq->front;
	while (cur)
	{
    
    
		QueueNode* Next = cur->next;
		free(cur);
		cur = Next;
	}
	pq->front = pq->tail = NULL;
}
//队尾入队列
void QueuePush(Queue* pq, QDatatype x)
{
    
    
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
    
    
		pq->front = pq->tail = newnode;
	}
	else
	{
    
    
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
//队头出队列
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
	//队列不能为空
	assert(!QueueEmpty(pq));
	//如果只有一个节点,防止tail野指针
	if (pq->front == pq->tail)
	{
    
    
		free(pq->front);
		pq->front = pq->tail = NULL;
	}
	//多个节点
	else
	{
    
    
		QueueNode* Next = pq->front->next;
		free(pq->front);
		pq->front = Next;
	}
}
//检测队列是否为空,为空返回1,非空返回0
int QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->front == NULL ? 1 : 0;
}
//获取队列中有效元素的个数
int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	int count = 0;
	QueueNode* cur = pq->front;
	while (cur)
	{
    
    
		++count;
		cur = cur->next;
	}
	return count;
}
//获取队列头部元素
QDatatype QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->front->data;
}
//获取队列队尾元素
QDatatype QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

(3)test.c测试

#include"Queue.h"

void TestQueue()
{
    
    
	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);
	}
	printf("\n");
	QueueDestroy(&q);
}
int main()
{
    
    
	TestQueue();
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_50886514/article/details/114372044