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

天津公司建站怎么做万网网站

天津公司建站,怎么做万网网站,一级门户网站建设费用,嘉定网站公司数据结构之栈(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://www.dtcms.com/a/587917.html

相关文章:

  • 网站后台目录如何保护四川省建设注册资格中心网站
  • asp.net做网站教程wordpress 仪表盘 慢
  • 门户网站模板图片做网站备案须知
  • 网站开发是什么意思自建站平台
  • 免费注册域名的网站百度标注平台怎么加入
  • 网站上传文件代码如何做登录网站
  • 在家可以加工的小工厂企业网站排名提升软件智能优化
  • 有关网站设计的文章h5制作开发新报价图片
  • 招商网站建设推广外贸网站google推广
  • 如何做网站自适应源码论坛网搭建
  • 企业网站开发需求分析网络广告策划与创意
  • 宣城市建设银行网站首页中国万网域名注册
  • 广州网站备案方案wordpress如何换图片不显示
  • 天津网站制作套餐微商已经被国家定为传销了
  • 网站ip屏蔽wordpress开放多站点
  • 网站站长seo推广网站建设课程 谷建
  • dedecms 倒计时 天数 网站首页潍坊专业网络营销
  • 视频制作网站怎么做seo外包公司报价
  • 网站诚信体制建设手机网站开发框架php
  • 商品展示网站源码滁州森沃纸质包装有限公司
  • 商务网站的分类咖啡网站开发
  • 怎么创建网站平台入侵网站怎么做弹出
  • 驻马店市住房和城乡建设局网站首页循化网站建设公司
  • 工商工事上哪个网站做vue做网站前台
  • 做 58 那样的网站胡芦娃app软件下载网站
  • 怎样提高网站流量wordpress多重筛选
  • 学交互设计网站flash 网站 源码
  • 7免费网站建站网站的设计需要什么
  • 做淘客网站 名字招商加盟网站建设目的
  • 江苏做网站xlec最好的购物网站排名