本文已参与[新人创作礼]活动,一起开启掘金创作之路
栈的基本框架图
1.栈的定义
**栈(Stack): **栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操作。
栈又被称为后进先出(Last in First Out)的线性表,简称LIFO。
2.栈的顺序表实现
对于顺序表,在C语言中表现为数组,进行栈的定义,需要考虑以下几个点:
1.栈数据的存储方式;
2.栈的大小;
3.栈顶指针。
(1)我们可以定义一个栈的结构体
struct Stack {
int *stack;
int top;
};
Stack就是接下来会用到的栈结构体
top即栈顶指针,top=-1表示空栈
(2)初始化栈
struct Stack* InitStack(int len) {
struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
p->stack = (int*)calloc(len, sizeof(int));
p->top = -1;
return p;
}
calloc用来定义p的空间 初始化 top=-1 ;
calloc() 函数用来动态地分配内存空间并初始化为 0,其原型为:
void* calloc (size_t num, size_t size);
calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
详请calloc的链接callochttp://c.biancheng.net/cpp/html/134.html
http://c.biancheng.net/cpp/html/134.html
(3)找栈头
int top(struct Stack* p)
{
return p->stack[p->top];
}
(4)清空栈
void StackClear(struct Stack* stk)
{
stk->top = -1;
}
只要将栈顶指针初始化即可
(5)判断栈空
bool StackEmpty(struct Stack* p) {
if (p->top == -1) {
return true;
}
return false;
}
(6)进栈
//进栈
void StackPushStack(struct Stack* stk, int e)
{
if (stk->top == maxn - 1)printf("栈已满");
return;
stk->data[++stk->top] = e;
}
首先判断栈是否满,不满则加入e
(7)出栈
void StackPopStack(struct Stack* stk)
{
while (stk->top != -1)
{
--stk->top;
}
}
如果为空栈的时候(stk->top=-1),即出栈完毕
源代码
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
struct Stack {
int *stack;
int top;
};
//初始化栈
struct Stack* InitStack(int len) {
struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
p->stack = (int*)calloc(len, sizeof(int));
p->top = -1;
return p;
}
//找栈头
int top(struct Stack* p)
{
return p->stack[p->top];
}
//清空栈
void StackClear(struct Stack* stk)
{
stk->top = -1;
}
//判断栈空
bool StackIsEmpty(struct Stack* stk)
{
if (stk->top == -1)return true;
return false;
}
//入栈
void StackPushStack(struct Stack* stk,int e)
{
stk->stack[++stk->top] = e;
}
//出栈
void StackPopStack(struct Stack* stk)
{
while (stk->top != -1)
{
--stk->top;
}
}
试题小训练
946.验证栈的序列https://leetcode-cn.com/problems/validate-stack-sequences/
思路:将数值加入到栈内,直到栈内的元素和出栈序列的数值相同,相同时指针移动;用栈模拟出栈入栈的过程,当popped中index指向的位置的元素和stack栈顶的元素一致时,出栈 并且
index++,最后判断stack是否为空
视频思路理解
源码如下
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
struct Stack {
int* stack;
int top;
};
struct Stack* InitStack(int len) {
struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
p->stack = (int*)calloc(len, sizeof(int));
p->top = -1;
return p;
}
bool StackEmpty(struct Stack* p) {
if (p->top == -1) {
return true;
}
return false;
}
int top(struct Stack* p) {
return p->stack[p->top];
}
void pop(struct Stack* p) {
(p->top)--;
return;
}
void push(struct Stack* p, int number) {
(p->top)++;
p->stack[p->top] = number;
return;
}
bool validateStackSequences(int* pushed, int pushedSize, int* popped, int poppedSize) {
struct Stack* a = InitStack(pushedSize);
int i = 0;
int j = 0;
while (i < pushedSize) {
if (StackEmpty(a)) {
push(a, pushed[i]);
i++;
}
else {
while (top(a) == popped[j]) {
pop(a);
j++;
if (StackEmpty(a)) {
break;
}
}
push(a, pushed[i]);
i++;
}
}
while (j < pushedSize) {
if (popped[j] == top(a)) {
pop(a);
}
j++;
}
if (StackEmpty(a)) {
return true;
}
return false;
}
int main()
{
int m;
scanf_s("%d", &m);
int* a = malloc(sizeof(int) * m);
for (int i = 0; i < m; i++)
{
scanf_s("%d", &a[i]);
}
int n;
scanf_s("%d", &n);
int* b = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++)
{
scanf_s("%d", &b[i]);
}
bool c = validateStackSequences(a, m, b, n);
printf("%d", c);
}
结果为0说明不是正确的出栈序列
结果为1说明是正确的出栈序列
小插曲
前几天懒了,玩了一整天游戏,整个人感觉都变废了,一整天都没有刷题;
我特别钦佩那些能够每天坚持发博客的人,他们每天刷题每天总结;
今天做了一道中等题差点把我给打趴下,题目都看不懂,差点放弃了了做题,还好感谢大家的支持让我上了一次热榜。
(这个是热榜链接blog.csdn.net/weixin_5818…),看着大家的鼓励支持,让我重新燃气了斗志,我不能辜负大家的期望!!!
同时我也希望可以勉励那些正在坚持着自己梦想的;
路,并不是一帆风顺的总是有许多崎岖的地方;千万不要放弃,咬咬牙就过去了,都坚持了那么久真的甘心放弃嘛?