当前位置: 首页 > news >正文

这次疫情贵州火了成都seo论坛

这次疫情贵州火了,成都seo论坛,购买商标去哪个网站,wordpress 3d云标签前言: 💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥 ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现栈 目录 什么是栈 栈的概念及结构 实现栈的方式 链表的优缺点: 顺序表的优缺点: 栈…

前言:

💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥

✨✨专栏:http://t.csdn.cn/oXkBa

⛳⛳本篇内容:c语言数据结构--C语言实现栈

目录

什么是栈

        栈的概念及结构

实现栈的方式

链表的优缺点:

顺序表的优缺点:

栈的实现

a.头文件的包含

 b.栈的定义

c.接口函数     

接口函数的实现

1.栈的初始化

2.销毁栈

3.入栈

4.检测栈是否为空

5.出栈

6.获取栈顶元素

7.获取栈中有效元素个数

完整代码

Test.c

Stack.h

Stack.c


什么是

        栈的概念及结构

:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为 栈顶 ,另一端称为 栈底 栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在 栈顶
出栈:栈的删除操作叫做出栈。 出数据也在 栈顶
栈的结构:

实现栈的方式

实现栈的方式有两种: 顺序表链表

链表的优缺点:

优点:

        1、任意位置插入删除O(1)

        2、按需申请释放空间

缺点:

        1、不支持下标随机访问

        2、CPU高速缓存命中率会更低

        先说链表实现栈的缺点:

  1. 额外内存开销:链表实现的栈需要为每个节点分配内存空间来存储数据和指针。相比于数组实现的栈,链表实现需要额外的内存开销来维护节点之间的指针关系,可能导致内存碎片化。

  2. 动态内存分配:链表实现的栈需要通过动态内存分配来创建和释放节点。这涉及到频繁的内存分配和释放操作,可能导致内存管理的复杂性和性能开销。在某些情况下,可能会出现内存分配失败或内存泄漏的问题。

  3. 指针操作开销:链表实现的栈需要通过指针进行节点之间的连接操作。这包括插入和删除节点时的指针修改,可能涉及到多个指针的更新。相比于数组实现的栈,链表实现的栈需要更多的指针操作,可能会带来一定的性能开销。

  4. 随机访问的限制:链表是一种顺序访问的数据结构,无法像数组一样通过索引进行随机访问。如果需要在栈中进行随机访问元素,链表实现的栈可能不太适合,而数组实现的栈更具优势。

顺序表的优缺点:

优点:1、尾插尾删效率不错。

        2、下标的随机访问。

        3、CPU高速缓存命中率会更高

缺点:

        1、前面部分插入删除数据,效率是O(N),需要挪动数据。

        2、空间不够,需要扩容。a、扩容是需要付出代价的b、一般还会伴随空间浪费。

        顺序表实现栈的优点

  1. 内存连续性:顺序表在内存中是连续存储的,相比于链表的动态内存分配,顺序表的元素在物理上更加紧凑。这样可以减少内存碎片化,提高内存的利用效率。

  2. 随机访问:顺序表可以通过索引直接访问栈中的元素,具有随机访问的能力。这意味着可以快速访问栈中任意位置的元素,而不需要遍历整个链表。

  3. 操作简单高效:顺序表的插入和删除操作只涉及元素的移动,不需要额外的指针操作和动态内存分配。这使得操作相对简单高效,并且在某些情况下比链表实现更快。

  4. 空间效率:相比于链表实现,顺序表不需要额外的指针来维护节点之间的连接关系,因此可以节省一定的空间开销。只需要存储元素本身和栈顶指针即可。

综上所述,用顺序表实现栈更好。

栈的实现

a.头文件的包含

#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<stdio.h>

 b.栈的定义

typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//栈顶int capacity;//栈的容量
}ST;

c.接口函数     

// 初始化栈
void STInit(ST* pst); // 入栈
void STPush(ST* pst, STDataType data); // 出栈
void STPop(ST* pst); // 获取栈顶元素
STDataType STTop(ST* pst); // 获取栈中有效元素个数
int STSize(ST* pst); // 检测栈是否为空,如果为空返回true,如果不为空返回false
bool STEmpty(ST* pst); // 销毁栈
void STDestroy(ST* pst);

接口函数的实现

1.栈的初始化

        pst->top表示栈的顶部指针,通常情况下,它指向栈顶元素的下一个位置,而不是指向当前栈顶元素。通过 pst->top 可以确定栈中元素的个数,打印的时候记得将 top - 1。

void STInit(ST* pst)
{assert(pst);//防止敲代码的人传过来是NULL指针pst->a = NULL;//栈底//top不是数组下标,不能理解成数组下标,因为栈只能拿到栈顶的元素,而数组可以随机访问拿到中间元素//pst->top=-1;//指向栈顶元素pst->top = 0;//指向栈顶元素的下一个位置pst->capacity = 0;}

分别解释一下各自的含义: 

  1.  pst 是指向栈的指针,指向栈的首节点或头节点。
  2. -> 是一个成员访问运算符,用于通过指针访问结构体或类的成员
  • pst ->a 是指向存储栈元素的数组的指针。栈中的元素通常被存储在数组中,通过 pst->a 可以访问和操作该数组。在 STInit 函数中, pst->a 被设置为 NULL,表示栈底为空,即栈中没有任何元素。

  • pst->capacity 表示栈的容量,即栈可以容纳的最大元素数量。当栈中元素的数量达到 pst->capacity 时,栈被认为已满,无法再进行入栈操作。在初始化时,pst->capacity 的值通常被设置为 0,表示栈的初始容量为 0。

  • pst->top 表示栈顶指针,它指向当前栈顶元素的下一个位置。在栈为空时,pst->top 的值为 0,表示栈底。随着元素的入栈和出栈操作,pst->top 的值会相应地增加或减少,指向栈中下一个元素的位置。

2.销毁栈

为了防止野指针的出现,栈销毁后记得将指针置空。

void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;
}

3.入栈

三元运算符

condition ? value1: value2 

它的含义是,如果条件condition为真(非0),则整个表达式的值为value1;如果条件为假(0),则整个表达式的值为value2

解析:

int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;

这段代码的执行顺序如下:

  1. 首先,评估条件pst->capacity == 0 这将检查  pst 指针所指向的结构体中的 capacity 成员是否等于 0
  2. 如果条件为真(pst->capacity 等于 0),则表达式的值为 4,将其赋给 newCapacity  
  3. 如果条件为假(pst->capacity不等于 0),则表达式的值为pst->capacity * 2,将其赋给 newCapacity

realloc函数:【C进阶】-- 动态内存管理_Dream_Chaser~的博客-CSDN博客

动图:

函数代码:


void STPush(ST* pst,STDataType x)
{if (pst->top == pst->capacity){int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;//返回的是realloc出来的内存块的地址pst->capacity = newCapacity;//把扩容后的空间大小赋值给栈容量}pst->a[pst->top] = x;//先放值pst->top++;//再++
}

【注意事项】

1️⃣检查栈的顶部指针 top 是否等于栈的容量 capacity 。如果这两个值相等,那么说明栈已经满了,无法再添加新的元素。

 2️⃣接着判断此时栈的容量是否是0,若是0,则把4赋值给newcapacity作为新的栈容量。此后若栈满了,则把此时栈满时的容量 * 2进行扩容,赋值给newcapacity作为新的栈容量。

3️⃣先放入新的元素入栈,接着pst->top指向栈顶元素的指针++

4.检测栈是否为空

        栈为空返回true,不为空返回false

bool STEmpty(ST* pst)//栈为空返回true,不为空返回false
{//写法一//assert(pst);//if (pst->top == 0)//{//	return true;//}//else//{//	return false;//}//写法二return pst->top == 0;
}
  • 当栈为空时,表示栈中没有任何元素。此时,栈顶指针 top 的值通常被设置为特定的初始值(例如0或-1),指向栈底或栈外。在这种情况下,栈顶指针没有指向有效的元素,因此栈被认为是空的。

  • 当栈非空时,表示栈中至少有一个元素。此时,栈顶指针top的值指向栈顶元素的位置。栈顶元素是最后一个被入栈的元素,也是最先被访问或移除的元素。只要栈中有元素存在,栈顶指针都会指向有效的位置。

        因此,在STEmpty(ST* pst)函数中,当栈为空时,即栈顶指针top的值为0(或其他特定初始值),我们返回 true 表示栈为空。反之,如果栈非空,即栈顶指针 top 的值大于0,我们返回 false 表示栈不为空。

5.出栈

        先用assert判断传过来的pst指针是否指向NULL。接着判断栈是否为NULL,为NULL,STEmpty(pst)返回true,!STEmpty(pst)就是false,断言失败,程序终止。反之断言成功,程序正常执行。

图解:

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

【注意事项】

          接着将指向栈顶的指针--,通过将栈顶指针top减一,可以将指针向栈底方向移动,从而使栈顶指向下一个元素。

        指针的移动并不会直接导致元素的销毁。指针的移动只是改变了栈顶指针的位置,使其指向了栈中的下一个元素。元素本身并不会被销毁,只是在后续的操作中,可能无法直接访问被移除的元素。

6.获取栈顶元素

图解:因为前面定义的时候pst->top=0,表示指向栈顶元素的下一个位置。

pst->top-1表示栈顶元素在数组中的索引。

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

        需要注意的是,在实际使用中,应确保栈不为空(即栈中有元素存在),才能执行取栈顶元素的操作。因此,在代码中使用了 assert(!STEmpty(pst)) 进行栈非空的断言校验。

代码执行:

7.获取栈中有效元素个数

图解:由图看出,pst->top此时是指向下标为4的位置的,所以栈此时的有效个数就为4

int STSize(ST* pst)
{assert(pst);return pst->top;
}

代码执行: 

完整代码

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void TestStack1()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);while (!STEmpty(&st)){printf("%d ", STTop(&st));//栈顶元素STPop(&st);}STDestroy(&st);
}
void TestStack2()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);printf("%d ", STTop(&st));STPush(&st, 3);STPush(&st, 4);printf("\n");printf("%d ", STTop(&st));//printf("%d", STSize(&st));//while (!STEmpty(&st))//{//	printf("%d ", STTop(&st));//栈顶元素//	STPop(&st);//}STDestroy(&st);
}
void TestStack3()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);//printf("%d", STSize(&st));STDestroy(&st);
}int main()
{TestStack1();//入栈出栈//TestStack2();//获取栈顶元素//TestStack3();//计算栈中有效元素个数 return 0;
}

Stack.h

#pragma once
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<stdio.h>
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//栈顶的位置int capacity;//栈的容量
}ST;void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst,STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool  STEmpty(ST* pst);
int STSize(ST*pst);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void STInit(ST* pst)
{assert(pst);pst->a = NULL;//栈底//top不是下标//pst->top=-1;//指向栈顶元素pst->top = 0;//指向栈顶元素的下一个位置pst->capacity = 0;}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;
}void STPush(ST* pst,STDataType x)
{if (pst->top == pst->capacity){int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;//true,4.false,括2倍STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));//返回值地址相等就是原地扩容,不同就是异地扩if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;//返回的是realloc出来的内存块的地址pst->capacity = newCapacity;//把扩容后的空间大小赋值给栈容量}pst->a[pst->top] = x;//先放值pst->top++;//再++
}void STPop(ST* pst)
{assert(pst);assert(!STEmpty(pst));pst->top--;
}STDataType STTop(ST* pst)
{assert(pst);assert(!STEmpty(pst));return pst->a[pst->top - 1];
}bool STEmpty(ST* pst)//栈为空返回true,不为空返回false
{//assert(pst);//if (pst->top == 0)//{//	return true;//}//else//{//	return false;//}return pst->top == 0;
}
int STSize(ST* pst)
{assert(pst);return pst->top;
}

        栈面试题还在持续更新中,感谢支持!


文章转载自:
http://chicory.fjglxh.cn
http://barytone.fjglxh.cn
http://cabb.fjglxh.cn
http://chinela.fjglxh.cn
http://anisodactylous.fjglxh.cn
http://balneology.fjglxh.cn
http://brahmacharya.fjglxh.cn
http://almighty.fjglxh.cn
http://bathinette.fjglxh.cn
http://cellulose.fjglxh.cn
http://aduertiser.fjglxh.cn
http://candidate.fjglxh.cn
http://alulae.fjglxh.cn
http://casuistics.fjglxh.cn
http://ceramic.fjglxh.cn
http://alveolus.fjglxh.cn
http://ceuta.fjglxh.cn
http://ark.fjglxh.cn
http://anagrammatism.fjglxh.cn
http://aniseikonic.fjglxh.cn
http://bowel.fjglxh.cn
http://cardiomyopathy.fjglxh.cn
http://accomodate.fjglxh.cn
http://boondockers.fjglxh.cn
http://butylene.fjglxh.cn
http://centum.fjglxh.cn
http://azygous.fjglxh.cn
http://bicommunal.fjglxh.cn
http://celerity.fjglxh.cn
http://bichromate.fjglxh.cn
http://aneuploid.fjglxh.cn
http://benignity.fjglxh.cn
http://annoit.fjglxh.cn
http://bacteriolysin.fjglxh.cn
http://badmintoon.fjglxh.cn
http://cecrops.fjglxh.cn
http://beanie.fjglxh.cn
http://agitative.fjglxh.cn
http://antiparallel.fjglxh.cn
http://assume.fjglxh.cn
http://burma.fjglxh.cn
http://byroad.fjglxh.cn
http://asphyxiation.fjglxh.cn
http://barker.fjglxh.cn
http://blather.fjglxh.cn
http://accuse.fjglxh.cn
http://autogenic.fjglxh.cn
http://airmobile.fjglxh.cn
http://catlap.fjglxh.cn
http://adurol.fjglxh.cn
http://bumpy.fjglxh.cn
http://alkali.fjglxh.cn
http://adiaphoresis.fjglxh.cn
http://acrobatic.fjglxh.cn
http://admonitory.fjglxh.cn
http://benthon.fjglxh.cn
http://brimfull.fjglxh.cn
http://bilharzia.fjglxh.cn
http://boots.fjglxh.cn
http://bilharziasis.fjglxh.cn
http://accessory.fjglxh.cn
http://carifta.fjglxh.cn
http://ammonite.fjglxh.cn
http://administrators.fjglxh.cn
http://asymptomatically.fjglxh.cn
http://businessman.fjglxh.cn
http://asynergia.fjglxh.cn
http://analysand.fjglxh.cn
http://ado.fjglxh.cn
http://catalytic.fjglxh.cn
http://behaviourist.fjglxh.cn
http://blooming.fjglxh.cn
http://chasmophyte.fjglxh.cn
http://audibly.fjglxh.cn
http://apotropaion.fjglxh.cn
http://bewilder.fjglxh.cn
http://antithetical.fjglxh.cn
http://bagpiper.fjglxh.cn
http://armigerous.fjglxh.cn
http://archaist.fjglxh.cn
http://archenemy.fjglxh.cn
http://beautification.fjglxh.cn
http://amaryllidaceous.fjglxh.cn
http://acalephe.fjglxh.cn
http://atmometry.fjglxh.cn
http://cerograph.fjglxh.cn
http://bulldyke.fjglxh.cn
http://aerotrain.fjglxh.cn
http://affrontedly.fjglxh.cn
http://acariasis.fjglxh.cn
http://asansol.fjglxh.cn
http://archdeaconry.fjglxh.cn
http://apocarp.fjglxh.cn
http://agamete.fjglxh.cn
http://attenuate.fjglxh.cn
http://analogise.fjglxh.cn
http://certainty.fjglxh.cn
http://blooper.fjglxh.cn
http://achromatophilia.fjglxh.cn
http://barometrograph.fjglxh.cn
http://www.tj-hxxt.cn/news/37924.html

相关文章:

  • 上海网站建设公司 1861web什么是网站优化
  • 福建中江建设公司网站百度的企业网站
  • 网站上一页下一页怎么做推广计划书范文
  • 天津做网站选津坤科技seo优化首页
  • 佛山做外贸网站服务下载安装百度一下
  • 赣州做网站的外链发布论坛
  • 有关应用网站互联网产品运营推广方案
  • 山东建设厅网站网址我赢网seo优化网站
  • 做园区门户网站的需求分析网络营销与传统营销的整合
  • 在国外社交网站做产品推广网站服务费一年多少钱
  • 烟台外贸网站建设免费培训网站
  • 机关单位网站建设合同一份完整的品牌策划方案
  • 景德镇市城市建设规划网站杭州优化公司哪家好
  • 佛山怎么做网站各种资源都有的搜索引擎
  • 怎么做代理人金沙网站seo接单平台
  • 深圳电商网站开发公司电影站的seo
  • 网站建设与开发试题推销一个产品的方案
  • 软件网站模版网站平台怎么推广
  • 制作网站教程搜索引擎营销的主要方法
  • 百度搜不到我的网站谷歌广告投放教程
  • wordpress慢数据库南宁seo标准
  • 山东平台网站建设多少钱seo入门课程
  • 用dw做的网站怎么上线免费网站推广网站短视频
  • 建设久久建筑网站网站设计规划
  • 政府门户网站建设和管理论文黄页引流推广网站入口
  • 做企业网站价格seo诊断方法步骤
  • 文化传媒公司网站建设网上销售
  • 网站建设宣传单页seo与sem的区别和联系
  • 江苏永坤建设有限公司网站seo管家
  • wordpress 帮助南京seo排名