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

2018春节放假安排 网站建设网站排名优化快速

2018春节放假安排 网站建设,网站排名优化快速,书画院网站模板,做蔬菜的网站有哪些数据结构之栈(C语言) 栈1 栈的概念与结构2 栈的初始化和销毁2.1 栈的初始化2.2 栈的销毁 3 入栈函数与出栈函数3.1 入栈函数3.2 出栈函数 4 取栈顶数据,获取数据个数 和 判空函数4.1 取栈顶数据与获取数据个数4.1.1 取栈顶数据4.1.2 获取数据…

数据结构之栈(C语言)

    • 1 栈的概念与结构
    • 2 栈的初始化和销毁
      • 2.1 栈的初始化
      • 2.2 栈的销毁
    • 3 入栈函数与出栈函数
      • 3.1 入栈函数
      • 3.2 出栈函数
    • 4 取栈顶数据,获取数据个数 和 判空函数
      • 4.1 取栈顶数据与获取数据个数
        • 4.1.1 取栈顶数据
        • 4.1.2 获取数据个数
      • 4.2 判空函数
    • 5 真题实战(有效的括号)

1 栈的概念与结构

栈是一种特殊的线性表,特殊在于其规定只允许在栈固定的一端进行数据插入和删除操作。数据插入和删除数据元素的一端叫做栈顶,另一端叫做栈底。栈中的元素遵从先进后出的原则。(我们可以把栈看成枪的弹夹,先压入的子弹后击发,后压入的子弹先击发)
压栈:栈的插入操作叫做压栈/进栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据也在栈顶。

本章使用数组来实现栈。
在这里插入图片描述
代码定义如下:

typedef int STDatatype;//对栈中存入的元素类型进行重命名,避免修改时误操作typedef struct Stack
{STDatatype* c;//所存入栈中的数据int top;//表示指向栈顶元素位置or栈顶数据的下一个位置int capacity;//表示栈的容量
}ST;

在上面代码中我们对在的每个节点中定义了三个变量,对于top这一项较为特殊,下文2.1中会对两种情况进行阐述。

2 栈的初始化和销毁

2.1 栈的初始化

我们应知在创建出一个新的栈后,这个新的栈应是一个空栈,如此也就意味着指向存储数据的指针STDatatype* c = NULL,表示容量的int capacity = 0。但对于top我们不能轻率的认为top == 0表示空栈时top所指向的是栈顶数据,如果这么认为的话会对后面的操作造成误导(比如对栈判空)。因为top既然在等于0时表示栈为空栈,而且top还指向着栈顶数据,那么此时在索引为0处(即top == 0处 )就应当存放有具体数据,然而此时栈却是空的,所以当top == 0表示空栈时top就不能指向着栈顶数据,而是指向栈顶数据的下一个位置。 反之同理,若想让top指向栈顶数据,则top == -1时才可表示空栈。(鱼和熊掌不可兼得,表示空栈为鱼,指向栈顶数据为熊掌)
如图所示:
在这里插入图片描述

//栈的初始化
void STInit(ST* pst)
{assert(pst);pst->c = NULL;//top指向栈顶数据的下一个位置pst->top = 0;//top指向栈顶数据//pst->top = -1;pst->capacity = 0;
}

我们之所以选择top指向栈顶元素的下一个位置这种定义,一是因为在诸多程序中变量为零都是判空的条件,如此设置有助于代码的一致性与可读性。二是因为top如此一来就可以等同于capacity的作用,直接反映栈中元素数量。三是因为简化了栈的判空并且减少了对栈边界的检查,top == 0时栈为空;最大容量为n时,top == n表示栈满。无需额外检查。

2.2 栈的销毁

由于本文中的栈是使用数组完成实现,故栈的销毁与顺序表的销毁一致。首先使用assert对数组断言(确定传参有效),然后释放掉动态内存,最后将top与capacity均置为0。
代码如下:

void STDestroy(ST* pst)
{assert(pst);free(pst->c);//释放动态内存pst->c = NULL;//首地址置为空pst->top = pst->capacity = 0;
}

3 入栈函数与出栈函数

3.1 入栈函数

经过初始化函数对栈进行操作后,数组为空,容量为零。所以在将数据压入栈中之前,我们要先对数组的容量进行检测,检查容量是否已满。如果满了,我们就进行扩容操作;反之,我们就直接插入即可。
对于内存函数的选择方面,由于扩容时会存在原本栈容量已经满的情况,此时不仅要扩大内存块,还要保留栈中原本的数据,所以应当选择realloc

void STPush(ST* pst, STDatatype x)
{assert(pst);//扩容if (pst->c == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDatatype* tmp = (STDatatype*)realloc(pst->c, newcapacity * sizeof(STDatatype));if (tmp == NULL){perror("realloc fail !");return;}pst->c = tmp;pst->capacity = newcapacity;}//扩容完毕后插入数据pst->c[pst->top] = x;//将数据插入到栈顶//注意这里要做出区分//此时top == 0 这个位置就是栈顶//但是top的指向是栈顶数据的下一个位置pst->top++;
}

3.2 出栈函数

出栈的操作只要在逻辑结构上将出栈数据移除即可,也就是通过索引top的加减完成出栈操作。此时有人可能会有疑问,既然其在物理结构上还存在于数组的内存块中,那么不会对栈满的判断造成影响吗?
因为我们在对top定义时,将其定义为指向栈顶数据的下一个位置,如此top==0就表示了空栈,top就表示栈中有几个数据,所以不会对栈满的判断造成影响。此外,当我们进行一次出栈后,出栈的数据虽然仍存在于数组的物理结构中,但是在下一次进行压栈操作后,刚才出栈数据的位置就会分配给新压入栈的数据,出栈的数据被新压入栈的数据覆盖掉。

void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);//top表示栈中数据个数//当top==0时,栈已经成空栈,不能再进行出栈操作pst->top--;
}

4 取栈顶数据,获取数据个数 和 判空函数

4.1 取栈顶数据与获取数据个数

4.1.1 取栈顶数据

因为top是指向栈顶数据的下一个位置,所以要想获得栈顶数据,索引应当等于top - 1。
在这里插入图片描述
代码如下:

STDatatype STTop(ST* pst)
{assert(pst);//确保传参有效assert(pst->top > 0);//确保栈不为空return pst->c[pst->top - 1];//top - 1为栈顶数据
}
4.1.2 获取数据个数

top就代表着栈中的数据个数,所以直接返回top即可。
代码如下:

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

4.2 判空函数

根据我们前面的定义,top == 0时为空栈。所以判空过程中如果top等于零就是真(true),top不等于0就是假(false)。故我们将返回值类型设置为布尔类型,便于直观表现判空结果。
代码如下:

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

5 真题实战(有效的括号)

在这里插入图片描述
输出样例:
在这里插入图片描述
这个题当中我们之所以选择用栈来解答就是因为栈独特的后进先出的特性,根据题目要求我们可以得出每个右括号都要与最近的未闭合的左括号匹配,那么每当识别到左括号就将其压入栈中,当识别到右括号时就将刚压入栈的左括号出栈顶与之匹配,如果不匹配也就意味着字符串非有效。
按照上述思路我们来完成实现(前提是上文中栈的基本结构已经编写完毕):
初阶版:

//因输出结果为true与false,故返回值类型定位布尔类型
bool isValid(char* s) {ST st;STInit(&st);while(*s){//识别括号,是左括号入栈if(*s == '(' || *s == '[' || *s == '{'){STPush(&st , *s);}//不是左括号是右括号,刚进栈的左括号出栈顶与右括号匹配else{//取栈顶元素char top = STTop(&st);//出栈顶STPop(&st);//匹不匹配只需看不匹配情况即可,如果匹配就继续执行循环,不匹配直接结束函数if(top == '(' && *s != ')'|| top == '[' && *s != ']'|| top == '{' && *s != '}'){STDestroy(&st);//即使不匹配也要及时销毁栈,避免内存泄漏return false;}}//每完成一次压栈或出栈操作字符串数组索引向后移一位++s;}return true;
}

提交后发现给出的四个样例均可通过,但当字符串中只有一个"["时,运行结果错误。在这里插入图片描述
这是因为左括号数量比右括号多,当最后一个左括号被压入栈中之后,没有右括号与其匹配,左括号依然存在于栈中。而程序运行完并没有对栈中进行判空,所以结果出错。
修改后:

//因输出结果为true与false,故返回值类型定位布尔类型
bool isValid(char* s) {ST st;STInit(&st);while(*s){//识别括号,是左括号入栈if(*s == '(' || *s == '[' || *s == '{'){STPush(&st , *s);}//不是左括号是右括号,刚进栈的左括号出栈顶与右括号匹配else{//取栈顶元素char top = STTop(&st);//出栈顶STPop(&st);//匹不匹配只需看不匹配情况即可,如果匹配就继续执行循环,不匹配直接结束函数if(top == '(' && *s != ')'|| top == '[' && *s != ']'|| top == '{' && *s != '}'){STDestroy(&st);return false;}}//每完成一次压栈或出栈操作字符串数组索引向后移一位++s;}//匹配完如果栈不为空,说明左括号比右括号多,数量不匹配bool ret = STEmpty(&st);STDestroy(&st);return ret;
}

再次提交发现仍然存在报错,当字符串中只有一个"]"时,运行结果错误。
在这里插入图片描述
由于没有左括号压入栈中,所以在取栈顶元素时就触发了assert断言的报错。
故在取栈顶元素之前,也应对栈进行判空操作。
最终修改后:

//因输出结果为true与false,故返回值类型定位布尔类型
bool isValid(char* s) {ST st;STInit(&st);while(*s){//识别括号,是左括号入栈if(*s == '(' || *s == '[' || *s == '{'){STPush(&st , *s);}//不是左括号是右括号,刚进栈的左括号出栈顶与右括号匹配else{//如果栈为空,字符串只有一个右括号if( STEmpty(&st) ){STDestroy(&st);return false;}//如果栈不为空,进行匹配//取栈顶元素char top = STTop(&st);//出栈顶STPop(&st);//匹不匹配只需看不匹配情况即可,如果匹配就继续执行循环,不匹配直接结束函数if(top == '(' && *s != ')'|| top == '[' && *s != ']'|| top == '{' && *s != '}'){STDestroy(&st);return false;}}//每完成一次压栈或出栈操作字符串数组索引向后移一位++s;}//匹配完如果栈不为空,说明左括号比右括号多,数量不匹配bool ret = STEmpty(&st);STDestroy(&st);return ret;
}

在这里插入图片描述
提交通过,题目解答完毕。

全文至此结束!!!
写作不易,不知各位老板能否给个一键三连或是一个免费的赞呢(▽)(▽),这将是对我最大的肯定与支持!!!谢谢!!!(▽)(▽)


文章转载自:

http://LJnbvuzT.xkjqg.cn
http://k4Nnn5cF.xkjqg.cn
http://68JWwLnt.xkjqg.cn
http://rqzOkI3Q.xkjqg.cn
http://q1RgA8sZ.xkjqg.cn
http://YFGK1UAy.xkjqg.cn
http://fdbAevLt.xkjqg.cn
http://U6rY5SRV.xkjqg.cn
http://O6Jx3M1m.xkjqg.cn
http://3V4501ZN.xkjqg.cn
http://3O04ELaI.xkjqg.cn
http://gkO5im2X.xkjqg.cn
http://4tiIEBws.xkjqg.cn
http://HNftzg4Q.xkjqg.cn
http://vnnVRz1e.xkjqg.cn
http://xQqzUiBY.xkjqg.cn
http://qjAtMxES.xkjqg.cn
http://dpWS6Q5M.xkjqg.cn
http://XrFMGPe9.xkjqg.cn
http://xiH8RzVa.xkjqg.cn
http://Kv5yCSIO.xkjqg.cn
http://XyMcJ13h.xkjqg.cn
http://GYI1wDoe.xkjqg.cn
http://OMjd2x5S.xkjqg.cn
http://n9cYdsHT.xkjqg.cn
http://BhC58POS.xkjqg.cn
http://xKQtTPhg.xkjqg.cn
http://j1WMyKnY.xkjqg.cn
http://6cd2rFQw.xkjqg.cn
http://kHzu5ivm.xkjqg.cn
http://www.dtcms.com/wzjs/681939.html

相关文章:

  • 不要验证码的广告网站《梦幻西游》官网
  • 电子商务网站总体框架设计2018网站建设合同范本
  • 百度公司做网站优化多少钱成都全程网络营销策划机构
  • 广州专业网站建设公司爱美刻在线制作网站
  • 英文网站建设运营连云港seo
  • 9861云南网站建设网站不备案做电影网站
  • 做网站的空间和服务器黄浦集团网站建设
  • 网站建设相关的网站网站开发资金投入
  • 网站建设技术清单在网站中添加搜索引擎
  • 上海企业免费建站wordpress开源企业主题
  • 网站规划主要内容网站建设创业规划书
  • 网站销售怎么做的做什么软件做网站效率最好
  • 杭州网站建设哪里好wordpress在本地运行很慢
  • 高端网站建设哪些好企业信用信息查询系统官网(全国)
  • asp.net网站制作视频教程室内设计公司取名字大全集
  • 如乐网站太原市建设交易中心网站首页
  • 电子商务平台的功能有哪些东莞seo关键词
  • 网站开发成本报表电商运营岗位职责
  • 网站搭建公司哪家好网站开发详细报价
  • 彩票类网站是如何做代理的两个wordpress共用一个数据库
  • 平台网站建设 厦门找网页模板的网站
  • 打开网站显示404wordpress自动采集发布
  • 交互式网站模板东莞网站建设 拉伸膜
  • 网站开发 售后服务协议中文域名网站
  • 石家庄市网站建设家教网站如何建设
  • 站群系统软件福州天成设计
  • 网站建设找汉狮继续接入备案 增加网站 区别
  • 犀牛网站建设公司网站开发前端与后端
  • 在什么网站可以做外贸出口劳保鞋免费快速建站网站
  • 网站正在建设中php龙海网络推广