栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
Stack.h中部分声明
#include
#include
#include
#include
#define INIT_CAPACITY 4
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; // 栈顶下标
int capacity; // 栈容量
}Stack;
(1).给栈动态开辟一块内存空间
(2).设置栈顶下标为0,即栈顶下标 top 代表栈中有效元素的个数
(3).设置栈的起始容量
void StackInit(Stack* pst)
{
assert(pst);
pst->a = (STDataType*)malloc(sizeof(STDataType) * INIT_CAPACITY);
if (pst->a == NULL)
{
printf("malloc failed\n");
exit(-1);
}
pst->top = 0;
pst->capacity = INIT_CAPACITY;
}
(1).若栈空间已满,使用realloc函数动态增容
(2).将入栈的数据放入栈中
(3).栈顶下标+1
void StackPush(Stack* pst, STDataType x)
{
assert(pst);
// 动态增容
if (pst->top == pst->capacity)
{
pst->capacity *= 2;
STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * pst->capacity);
if (tmp == NULL)
{
printf("realloc failed\n");
exit(-1);
}
pst->a = tmp;
}
pst->a[pst->top] = x;
pst->top++;
}
(1).判断栈是否为空
(2).栈顶下标-1
void StackPop(Stack* pst)
{
assert(pst);
assert(!StackEmpty(pst));
pst->top--;
}
(1).判断栈是否为空
(2).获取栈顶元素
STDataType StackTop(Stack* pst)
{
assert(pst);
assert(!StackEmpty(pst));
return pst->a[pst->top - 1];
}
栈顶下标即为栈中有效元素个数
int StackSize(Stack* pst)
{
assert(pst);
return pst->top;
}
由于栈顶下标代表栈中有效元素个数,所以只需判断栈顶下标是否为0即可
bool StackEmpty(Stack* pst)
{
assert(pst);
return pst->top == 0;
}
(1).将栈顶下标和栈的容量置为0
(2).释放掉动态开辟的内存空间
void StackDestroy(Stack* pst)
{
assert(pst);
pst->top = pst->capacity = 0;
free(pst->a);
pst->a = NULL;
}
Stack.h
#pragma once
#include
#include
#include
#include
#define INIT_CAPACITY 4
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; // 栈顶下标
int capacity; // 栈容量
}Stack;
// 栈的初始化
void StackInit(Stack* pst);
// 入栈
void StackPush(Stack* pst, STDataType x);
// 出栈
void StackPop(Stack* pst);
// 获取栈顶元素
STDataType StackTop(Stack* pst);
// 获取栈的元素个数
int StackSize(Stack* pst);
// 判断栈是否为空,为空返回true,非空返回false
bool StackEmpty(Stack* pst);
// 打印
void print(Stack* pst);
// 销毁栈
void StackDestroy(Stack* pst);
Stack.c
#include"Stack.h"
// 打印
void print(Stack* pst)
{
assert(pst);
int i = 0;
for (i = 0; i < pst->top; i++)
{
printf("%d ", pst->a[i]);
}
printf("\n");
}
// 判断栈是否为空,为空返回true,非空返回false
bool StackEmpty(Stack* pst)
{
assert(pst);
return pst->top == 0;
}
// 栈的初始化
void StackInit(Stack* pst)
{
assert(pst);
pst->a = (STDataType*)malloc(sizeof(STDataType) * INIT_CAPACITY);
if (pst->a == NULL)
{
printf("malloc failed\n");
exit(-1);
}
pst->top = 0;
pst->capacity = INIT_CAPACITY;
}
// 入栈
void StackPush(Stack* pst, STDataType x)
{
assert(pst);
// 动态增容
if (pst->top == pst->capacity)
{
pst->capacity *= 2;
STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * pst->capacity);
if (tmp == NULL)
{
printf("realloc failed\n");
exit(-1);
}
pst->a = tmp;
}
pst->a[pst->top] = x;
pst->top++;
}
// 出栈
void StackPop(Stack* pst)
{
assert(pst);
assert(!StackEmpty(pst));
pst->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* pst)
{
assert(pst);
assert(!StackEmpty(pst));
return pst->a[pst->top - 1];
}
// 获取栈的元素个数
int StackSize(Stack* pst)
{
assert(pst);
return pst->top;
}
// 销毁栈
void StackDestroy(Stack* pst)
{
assert(pst);
pst->top = pst->capacity = 0;
free(pst->a);
pst->a = NULL;
}
TestStack.c
#include"Stack.h"
void TestStack01()
{
Stack st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
StackPush(&st, 4);
print(&st);
StackPop(&st);
print(&st);
StackPop(&st);
StackPop(&st);
StackPop(&st);
StackPop(&st);
StackDestroy(&st);
}
int main()
{
TestStack01();
}
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
Queue.h 中部分声明
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
将队头和队尾指针置为空
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
}
(1).若队列为空,使 head 和 tail 指针指向新申请的结点
(2).若队列不为空,使 tail->next 指向新申请的结点,并将 tail 移动到新的尾(tail = tail->next)
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
if (newNode == NULL)
{
printf("malloc failed\n");
exit(-1);
}
newNode->data = x;
newNode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newNode;
}
else
{
pq->tail->next = newNode;
pq->tail = pq->tail->next;
}
}
出队列相当于头删
(1).判断队列是否为空,为空断言报错
(2).保存住第二个结点的地址
(3).释放掉第一个结点
(4).改变 head 指针使其指向新的头
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
(1).判断队列是否为空,为空断言报错
(2).返回 head->data
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
(1).判断队列是否为空,为空断言报错
(2).返回 tail->data
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
遍历链表得到链表元素的个数即可
int QueueSize(Queue* pq)
{
assert(pq);
int count = 0;
QueueNode* cur = pq->head;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
检测 head 指针是否为空即可
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
遍历链表逐个销毁即可
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
}
Queue.h
#pragma once
#include
#include
#include
#include
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
// 队列初始化
void QueueInit(Queue* pq);
// 入队
void QueuePush(Queue* pq, QDataType x);
// 出队
void QueuePop(Queue* pq);
// 判空
bool QueueEmpty(Queue* pq);
// 获取队尾元素
QDataType QueueBack(Queue* pq);
// 获取队头元素
QDataType QueueFront(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);
// 队列元素个数
int QueueSize(Queue* pq);
Queue.c
#include"Queue.h"
// 队列初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
}
// 入队
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
if (newNode == NULL)
{
printf("malloc failed\n");
exit(-1);
}
newNode->data = x;
newNode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newNode;
}
else
{
pq->tail->next = newNode;
pq->tail = pq->tail->next;
}
}
// 出队
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
// 判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
// 获取队尾元素
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
// 获取队头元素
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
// 销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
}
// 队列元素个数
int QueueSize(Queue* pq)
{
assert(pq);
int count = 0;
QueueNode* cur = pq->head;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}