👑个人主页:啊Q闻
🎇收录专栏:《数据结构》
🎉前路漫漫亦灿灿
前言
栈是一种特殊的线性表,我们在有了顺序表和链表的知识的基础上,再来学习栈,掌握起来就更轻松了。
一.初识栈
1.栈的概念
栈是一种特殊的线性表,它的特殊性体现在只允许在固定的一端进行插入和删除操作,其遵循先入后出的的规则。
我们将进行数据插入和数据删除操作的一端称为栈顶,另一端则称为栈底。
栈的插入操作叫做压栈(或者进栈或者入栈),栈的删除操作叫做出栈,这两种操作都是在栈顶进行。
2.栈的结构
入栈出栈示意图:
从入栈出栈示意图中,我们发现:1是最先进入栈中,却是最后出栈的,印证了栈的先入后出规则。
二.栈的实现
栈的实现可以用链表也可以用数组,我们选择使用数组,因为数组在尾上插入删除更简单。stack.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//栈顶int capacity;//容量
}Stack;
//初始化栈
void StackInit(Stack* s);
//入栈
void StackPush(Stack* s,STDataType x);
//出栈
void StackPop(Stack* s);
//获取栈顶元素
STDataType StackTop(Stack* s);
//获取栈中有效元素个数
int StackSize(Stack* s);
//检测栈是否为空,为空返回0
bool StackEmpty(Stack* s);
//销毁栈
void StackDestroy(Stack* s);
stack.c
注意:我们入栈出栈均是在栈顶,所以在数组中就是实现在尾部的插入与删除。
#include"stack.h"
//初始化栈
void StackInit(Stack* s)
{assert(s);s->a = NULL;s->top = 0;s->capacity = 0;
}
//入栈
void StackPush(Stack* s,STDataType x)
{assert(s);if (s->top == s->capacity)//容量不够就进性扩容{int newcapacity = s->capacity == 0 ? 4 :s->capacity * 2;STDataType* tmp = (STDataType*)realloc(s->a, (newcapacity * sizeof(STDataType)));if (tmp == NULL){perror("realloc fail\n");return;}s->a = tmp;s->capacity = newcapacity;}s->a[s->top] = x;s->top++;
}
//检测栈是否为空,为空返回false
bool StackEmpty(Stack* s)
{assert(s);return s->top == 0;
}
//出栈
void StackPop(Stack* s)
{assert(s);assert(!StackEmpty(s));s->top--;
}
//获取栈顶元素
STDataType StackTop(Stack* s)
{assert(s);assert(!StackEmpty(s));return s->a[s->top - 1];
}
//获取栈中有效元素个数
int StackSize(Stack* s)
{assert(s);return s->top;
}
//销毁栈
void StackDestroy(Stack* s)
{free(s->a);s->a = NULL;s->capacity = s->top = 0;
}
详解:
入栈:
当容量不够时就进行扩容,数组的扩容我们首先要用一个三目操作判断原来的容量是否为 0,为0我们就给它赋值4,不为0就是直接扩容,一般是成二倍扩容。
利用realloc对原有的数组进行扩容。
扩容后在插入数据,top++指向尾部元素的下一位。
出栈
我们出栈前先判断栈是否为空,如果为空,就无法进行出栈操作。
出栈直接top--。
获取栈顶元素和栈顶中有效元素
获取栈顶元素之前,要保证栈顶不为空。
因为top指向的是栈顶元素的下一个,所以我们用top-1.
获取栈中有效元素,因为数组下标是从0开始,所以最后下标会比实际有效元素少1。但是正好的是top是指向有效元素的下一个,所以top的值就是有效元素个数。
初始化栈和销毁栈
对于销毁栈,因为我们是在扩容时用realloc对数组a进行扩容,所以用free释放扩容的部分。
test.c
#include"stack.h"
int main()
{Stack s;StackInit(&s);StackPush(&s, 1);StackPush(&s, 2);StackPush(&s, 3);StackPush(&s, 4);while(!StackEmpty(&s)){int top = StackTop(&s);printf("%d\n", top);StackPop(&s);}StackDestroy(&s);return 0;
}
感谢阅读,如果对你有帮助的话,三连支持一下吧