一、栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据也在栈顶。
二、栈的实现(使用VS2022的C语言)
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
栈常用的接口包括:
1.初始化、销毁
2.入栈、出栈、取出栈顶元素
3.判空、统计长度
在 Stack.h 中:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
// 初始容量
#define INIT_CAPACITY 4
// 扩容倍率
#define EXPANSION_MULTIPLE 2
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int size;
int capacity;
} Stack, * pStack;
// 初始化、销毁
void StackInit(pStack pst);
void StackDestroy(pStack pst);
// 入栈、出栈、取出栈顶元素
void StackPush(pStack pst, STDataType x);
void StackPop(pStack pst);
STDataType StackTop(pStack pst);
// 判空、统计长度
bool StackEmpty(pStack pst);
int StackSize(pStack pst);
在 Stack.c 中:
1.初始化、销毁
// 初始化、销毁
void StackInit(pStack pst)
{
assert(pst);
pst->arr = NULL;
pst->size = 0;
pst->capacity = 0;
}
void StackDestroy(pStack pst)
{
assert(pst);
free(pst->arr);
pst->size = 0;
pst->capacity = 0;
}
2.入栈、出栈、取出栈顶元素
// 入栈、出栈、取出栈顶元素
void StackPush(pStack pst, STDataType x)
{
assert(pst);
// 检查扩容问题
if (pst->size == pst->capacity)
{
int newCapacity = pst->capacity == 0 ? INIT_CAPACITY : pst->capacity * EXPANSION_MULTIPLE;
STDataType* temp = (STDataType*)realloc(pst->arr, newCapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc failed");
return;
}
pst->arr = temp;
pst->capacity = newCapacity;
}
pst->arr[pst->size++] = x;
}
void StackPop(pStack pst)
{
assert(pst);
assert(!StackEmpty(pst)); // 防止为空
// 直接减减忽略当前位置
--pst->size;
}
STDataType StackTop(pStack pst)
{
assert(pst);
assert(!StackEmpty(pst));
// 注意这里 pst->size下标 不是最后一个元素
return pst->arr[pst->size - 1];
}
3.判空、统计长度
// 判空、统计长度
bool StackEmpty(pStack pst)
{
assert(pst);
return pst->size == 0;
}
int StackSize(pStack pst)
{
assert(pst);
return pst->size;
}
三、完整 Stack.c 源代码
#include "Stack.h"
// 初始化、销毁
void StackInit(pStack pst)
{
assert(pst);
pst->arr = NULL;
pst->size = 0;
pst->capacity = 0;
}
void StackDestroy(pStack pst)
{
assert(pst);
free(pst->arr);
pst->size = 0;
pst->capacity = 0;
}
// 入栈、出栈、取出栈顶元素
void StackPush(pStack pst, STDataType x)
{
assert(pst);
// 检查扩容问题
if (pst->size == pst->capacity)
{
int newCapacity = pst->capacity == 0 ? INIT_CAPACITY : pst->capacity * EXPANSION_MULTIPLE;
STDataType* temp = (STDataType*)realloc(pst->arr, newCapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc failed");
return;
}
pst->arr = temp;
pst->capacity = newCapacity;
}
pst->arr[pst->size++] = x;
}
void StackPop(pStack pst)
{
assert(pst);
assert(!StackEmpty(pst)); // 防止为空
// 直接减减忽略当前位置
--pst->size;
}
STDataType StackTop(pStack pst)
{
assert(pst);
assert(!StackEmpty(pst));
// 注意这里 pst->size下标 不是最后一个元素
return pst->arr[pst->size - 1];
}
// 判空、统计长度
bool StackEmpty(pStack pst)
{
assert(pst);
return pst->size == 0;
}
int StackSize(pStack pst)
{
assert(pst);
return pst->size;
}