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