目录
前言
一、栈的定义
二、栈的表示和实现
1.定义
2.初始化
3.入栈
4.出栈
5.销毁顺序栈
6.清空顺序栈
7.判断栈是否为空
8.顺序栈的长度
9.遍历顺序栈
10.完整代码
前言
本片博客介绍的是栈的用法。
一、栈的定义
栈是一种具有特定操作的数据结构,它按照"先进后出"的原则存储和访问数据。栈具有两个基本操作,分别为入栈(push)和出栈(pop)。入栈将元素放入栈的顶部,出栈则将栈顶的元素取出。栈在计算机科学中广泛应用,例如函数调用、表达式求值、递归算法等。
二、栈的表示和实现
1.定义
我们一般使用顺序表来表示栈。使用一段连续的存储空间存储栈中的元素。
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef struct{
int * base;// 栈底指针
int * top; // 栈顶指针
int stacksize;
}SeqStack;
2.初始化
栈初始化的时候,给栈的基址分配存储空间,初始化之后,栈顶和栈底相同。
// 构造一个空栈
int initSeqStack(SeqStack * seqStack){
seqStack->base = (int *)malloc(sizeof(int) * STACK_INIT_SIZE);
if (!seqStack->base) {
return 0;
}
seqStack->top = seqStack->base;
seqStack->stacksize = STACK_INIT_SIZE;
return 1;
}
3.入栈
入栈的时候,我们首先判断下顺序栈是否已满,如果栈满则需要追加存储空间。然后入栈,栈顶指针上移。
// 入栈
int push(SeqStack * seqStack, int element){
// 如果栈满,则追加存储空间
if (seqStack->top - seqStack->base >= seqStack->stacksize) {
seqStack->base = (int *)realloc(seqStack->base, (seqStack->stacksize + STACKINCREMENT) * sizeof(int));
if (!seqStack->base) {
return 0; // 存储分配失败
}
seqStack->top = seqStack->base + seqStack->stacksize; // 栈顶指针重新定位
seqStack->stacksize += STACKINCREMENT; // 更新栈的大小
}
*(seqStack->top) = element; // 将元素压入栈顶
seqStack->top++; // 栈顶指针上移
return 1; // 入栈成功
}
4.出栈
出栈的时候,首先判断栈是否为空,然后取出栈顶元素。
// 出栈
int popSeqStack(SeqStack *seqStack, int *element){
if (seqStack->top == seqStack->base) {
return 0; // 栈空,无法出栈
}
*element = *(--seqStack->top); // 出栈,栈顶指针下移
return 1; // 出栈成功
}
5.销毁顺序栈
销毁栈的时候,释放栈的存储空间,置空栈顶和栈底。
// 销毁顺序栈
int destroySeqStack(SeqStack *seqStack){
free(seqStack->base); // 释放存储空间
seqStack->base = seqStack->top = NULL; // 栈底指针和栈顶指针置空
seqStack->stacksize = 0; // 栈大小置为0
return 1; // 销毁成功
}
6.清空顺序栈
清空栈,栈顶指针回栈底。
// 清空顺序栈
int clearSeqStack(SeqStack *seqStack){
seqStack->top = seqStack->base; // 栈顶指针回归栈底
return 1; // 清空成功
}
7.判断栈是否为空
入栈的时候,我们首先判断下顺序栈是否已满,如果栈满则需要追加存储空间。然后入栈,栈顶指针上移。
// 栈是否为空
int seqStackEmpty(SeqStack * seqStack){
return seqStack->top == seqStack->base;
}
8.顺序栈的长度
// 顺序栈的长度
int seqStackLength(SeqStack * seqStack){
int length = seqStack->top - seqStack->base;
return length;
}
9.遍历顺序栈
// 遍历顺序栈
void traverseSeqStack(SeqStack * seqStack){
printf("遍历栈中元素:");
int *p = seqStack->base;
while (p < seqStack->top) {
printf("%d ", *p++);
}
printf("\n");
}
10.完整代码
#include <stdlib.h>
#include <stdio.h>
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef struct{
int * base;// 栈底指针
int * top; // 栈顶指针
int stacksize;
}SeqStack;
#pragma mark -- 栈的常用操作
// 构造一个空栈
int initSeqStack(SeqStack * seqStack){
seqStack->base = (int *)malloc(sizeof(int) * STACK_INIT_SIZE);
if (!seqStack->base) {
return 0;
}
seqStack->top = seqStack->base;
seqStack->stacksize = STACK_INIT_SIZE;
return 1;
}
// 入栈
int push(SeqStack * seqStack, int element){
// 如果栈满,则追加存储空间
if (seqStack->top - seqStack->base >= seqStack->stacksize) {
seqStack->base = (int *)realloc(seqStack->base, (seqStack->stacksize + STACKINCREMENT) * sizeof(int));
if (!seqStack->base) {
return 0; // 存储分配失败
}
seqStack->top = seqStack->base + seqStack->stacksize; // 栈顶指针重新定位
seqStack->stacksize += STACKINCREMENT; // 更新栈的大小
}
*(seqStack->top) = element; // 将元素压入栈顶
seqStack->top++; // 栈顶指针上移
return 1; // 入栈成功
}
// 打印栈中的数据元素
void printSeqStack(SeqStack * seqStack){
printf("栈中的元素:\n");
int * p = seqStack->base;
while (p < seqStack->top) {
printf("%d\t",*p);
p++;
}
printf("\n");
}
// 获取栈顶元素
int getSeqStackTop(SeqStack * seqStack, int * stackTopElement){
if (seqStack->top == seqStack->base) {
return 0; // 栈空,无栈顶元素
}
*stackTopElement = *(seqStack->top - 1); // 获取栈顶元素
return 1;
}
// 出栈
int popSeqStack(SeqStack *seqStack, int *element){
if (seqStack->top == seqStack->base) {
return 0; // 栈空,无法出栈
}
*element = *(--seqStack->top); // 出栈,栈顶指针下移
return 1; // 出栈成功
}
// 销毁顺序栈
int destroySeqStack(SeqStack *seqStack){
free(seqStack->base); // 释放存储空间
seqStack->base = seqStack->top = NULL; // 栈底指针和栈顶指针置空
seqStack->stacksize = 0; // 栈大小置为0
return 1; // 销毁成功
}
// 清空顺序栈
int clearSeqStack(SeqStack *seqStack){
seqStack->top = seqStack->base; // 栈顶指针回归栈底
return 1; // 清空成功
}
// 栈是否为空
int seqStackEmpty(SeqStack * seqStack){
return seqStack->top == seqStack->base;
}
// 顺序栈的长度
int seqStackLength(SeqStack * seqStack){
int length = seqStack->top - seqStack->base;
return length;
}
// 遍历顺序栈
void traverseSeqStack(SeqStack * seqStack){
printf("遍历栈中元素:");
int *p = seqStack->base;
while (p < seqStack->top) {
printf("%d ", *p++);
}
printf("\n");
}
// 测试各个方法
void testSeqStack(void){
SeqStack seqStack;
printf("栈初始化.......\n");
if(initSeqStack(&seqStack)){
printf("栈初始化成功\t✅\n");
}else{
printf("栈初始化失败\n");
return;
}
// 入栈
printf("入栈.......\n");
for (int i = 1; i <= 10; i++) {
if (push(&seqStack, i)) {
printf("%d入栈成功\t✅\n", i);
} else {
printf("入栈失败!");
}
}
// 打印栈中元素
printf("\n********************\t打印栈栈中元素\t********************\n");
printSeqStack(&seqStack);
printf("顺序栈的长度:%d\n",seqStackLength(&seqStack));
// 获取栈顶元素
int topElement;
if (getSeqStackTop(&seqStack, &topElement)) {
printf("栈顶元素:%d\n", topElement);
} else {
printf("栈为空,无法获取栈顶元素!\n");
}
// 出栈
int popElement;
if (popSeqStack(&seqStack, &popElement)) {
printf("出栈元素:%d\n", popElement);
} else {
printf("栈为空,无法出栈!\n");
}
// 打印栈中元素
printf("\n********************\t打印栈栈中元素\t********************\n");
printSeqStack(&seqStack);
// 清空栈
clearSeqStack(&seqStack);
printf("清空栈后,栈是否为空:%d\n", seqStackEmpty(&seqStack));
}
int main(int argc, const char *argv[]) {
testSeqStack();
return 0;
}