栈的概念和结构以及实现

news/2025/2/14 0:56:51/
1.
1.1栈的概念及结构
栈:一种特殊的线性表,其只允许在
固定的一端 进行 插入和删除 元素操作。 进行数据插入和删除 操作的一端称为 栈顶 ,另一端称为 栈底 。栈中的数据元素遵守 后进先出 LIFO (Last in First Out) 的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,
入数据在栈顶
出栈: 栈的删除操作叫做出栈。 出数据也在栈顶
特点:栈只能在栈顶进行插入和删除。

按惯例一般出栈顺序是4 3 2 1,但一定是4 3 2 1吗?答案:不一定是。 

也有可能是4 3 2 1;1 2 3 4;3 2 4 1..... 但 3 1 2 4是绝对不可能的。

2.栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为 数组在尾上插入数据的代价比较小。

数组栈:完美符合栈固定一端的插入和删除的操作; 

如果使用单链表来模拟实现数组栈,用头做栈顶,尾做栈底。 

栈的初始化

void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}

如果我们在初始化的时候top的初始值是0,top就指向4后面,如果top想指向4本身就要初始值赋值给-1。

所以想top指向栈顶数据就初始化为-1,top想指向栈顶数据的下一个位置初始化为0。

栈的销毁


void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}

 栈的插入

void STPush(ST* ps, Stacktype x)
{assert(ps);if (ps->top== ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;Stacktype* tmp = (Stacktype*)realloc(ps->a,sizeof(Stacktype) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

布尔值检查

bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

栈的删除

void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}

返回栈顶元素

Stacktype STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}

 栈的大小

int STsz(ST* ps)
{assert(ps);return ps->top;
}

完整代码实现

头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int Stacktype;
typedef struct Stack
{Stacktype* a;int top;//栈顶 相当于szint capacity;//扩容
}ST;void STInit(ST*ps);//初始化
void STDestroy(ST* ps);//销毁void STPush(ST* ps, Stacktype x);//插入
void STPop(ST* ps);//删除int STsz(ST* ps);//空间大小
Stacktype STTop(ST* ps);//栈顶
bool STEmpty(ST* ps);//布尔值检查

两个源文件: 函数代码实现Stack.c与测试用例test.c

Stack.c

#include"Stack.h"
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STPush(ST* ps, Stacktype x)
{assert(ps);if (ps->top== ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;Stacktype* tmp = (Stacktype*)realloc(ps->a,sizeof(Stacktype) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}Stacktype STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}
int STsz(ST* ps)
{assert(ps);return ps->top;
}

test.c 

#include"Stack.h"
void test1()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);while (!STEmpty(&st)){int top = STTop(&st);printf("%d\n", top);STPop(&st);}STDestroy(&st);
}
int main()
{test1();return 0;
}

void test1()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);printf("%d ",STTop(&st));STPop(&st);STPush(&st, 3);STPush(&st, 4);while (!STEmpty(&st)){int top = STTop(&st);printf("%d ", top);STPop(&st);}STDestroy(&st);
}
int main()
{test1();return 0;
}


http://www.ppmy.cn/news/491720.html

相关文章

POJ-2777

题意 给定一个区间长度为l&#xff0c;共有t种颜色&#xff0c;o个操作。 C a b x 表示把a到b染成第x种颜色&#xff0c;P a b 表示查询a b间共有几种颜色。 初始状态下所有颜色为1&#xff0c;我就是因为这一点WA了几次 题解 t最大才30&#xff0c;颜色直接二进制压缩即可…

poj2777(线段树)

题目链接&#xff1a;https://vjudge.net/problem/POJ-2777 题意&#xff1a;有L块连续的板子&#xff0c;每块板子最多染一种颜色&#xff0c;有T种(<30)颜色&#xff0c;刚开始将所有板子染成颜色1&#xff0c;O次操作&#xff08;包括将[a,b]染成颜色k&#xff0c;和询问…

POJ2777【线段树】

一直以来就是这么写&#xff0c;很稳。 大晚上先贴个代码吧&#xff0c;下次给加注释。 const int Maxn 1e5 10;struct Seg{int Left, Right;int col;int _col; }node[Maxn<<2];void pushUp(int num){node[num].col node[num<<1].col|node[num<<1|1].co…

POJ 2777 Count Color

题目链接&#xff1a;http://poj.org/problem?id2777 解题思路&#xff1a;比较巧妙&#xff0c;状态压缩----最多三十种颜色&#xff0c;每一位表示每个颜色状态&#xff0c;那么使用逻辑或运算即可避免颜色重复计算的问题&#xff0c;统计颜色的时候判断1的位数即可。 延迟标…

POJ2777 Count Color

题意&#xff1a; 一段区间从1-n的初始颜色为1&#xff0c;每次进行两种操作 1&#xff0c;C a b c 把[a,b]这个区间染成颜色c。 2&#xff0c;P a b查询[a,b]区间内有多少种颜色。 思路&#xff1a; 首先题目保证染色的颜色数少于30种这是关键。我们需要将30种颜色的有无与…

线段树进阶-染色问题 附poj-2777题解

区域染色覆盖问题 假设某大学有一面文化墙&#xff0c;各个学院都可以在上面涂色&#xff0c;要求涂色区域高必须和墙一样&#xff0c;宽度任意但必须是整数&#xff08;以米为单位&#xff09;。涂色可以覆盖其他学院的涂色。现在若干个学院涂色之后最终这面墙上能看见多少种颜…

poj 2777 Count 线段树区间覆盖

http://poj.org/problem?id2777 跟贴报纸差不多&#xff0c;还不用离散化。 本身木棍的颜色是0&#xff0c;也算一种颜色&#xff0c;给木棍涂颜色&#xff0c;颜色用数字代替是1~30&#xff0c;不过是随时询问&#xff0c;不像贴报纸就问一次。 这个就要注意效率&#xff0c;…

洛谷P2777

玄学题&#xff0c;一开始我居然看成了单调队列,emmmm 贪心&#xff1a;每个人的最优的分时a[i]n; 其余要想他得到冠军&#xff0c;就要比他高分的人获得的最大得分是a[i]n,要让初始分数最高的人拿到最低的排名&#xff0c;证明只可意会不可言传&#xff0c;OI贪心就是比较玄学…