前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >栈和队列(1)

栈和队列(1)

作者头像
用户11039545
发布2024-05-24 13:48:11
390
发布2024-05-24 13:48:11
举报
文章被收录于专栏:c语言c语言

现在是个激动人心的时刻,因为我们来到了栈和队列的章节。

栈是一种特殊的线性表,只允许在一端进行插入和删除操作。进入数据插入和删除的一端叫作栈顶,另一端称为栈底。具有后进先出的特点。

压栈:数据的插入操作叫作进栈/入栈/压栈。

出栈:栈的删除操作叫作出栈,出栈也在栈顶。

栈的实现可以用数组或者线性表实现,相对而言,数组实现更优,因为数组在尾上插入的代价较小。

队列的表示和实现:

队列只允许在一端进行插入操作,在另一端进行删除操作。具有先进先出的特点。

入队列:进入插入操作的一端为队尾。

出队列:进行删除操作的一端为队头。

关于原地扩容和异地扩容:

异地扩容就是在新的地方开辟一个新的空间。

以上代码测试出如果是一样的,那么就是原地扩容,如果不一样,就是异地扩容。

此时地址是一样的。但是当我们把扩容的空间增大,地址不一样。

数据都在内存里,在堆上。

不会直接访问数据。在缓存,就叫做缓存命中。如果不在缓存,就叫作不命中,要把数据从内存加载到缓存,再访问。

实现静态的栈:

代码语言:javascript
复制
#define N 10
struct Stack
{
   int a[N];
};

动态的栈:

Stack.h

代码语言:javascript
复制
#pragma once
#include<stdio.h>
#innclude<stdlib.h>
#include<stdbool.h>
typedef int STDataType;
struct Stack
{
   STDataType* a;
   int top;
   int capacity;
}ST;

void STInit(ST* pst);
void STDestory(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

代码语言:javascript
复制
#include"Stack.h"
//初始化和销毁
void STInit(ST* pst)
{
    assert(pst);
    pst->a=NULL;
    pst->top=0;
    pst->capcity=0;
}
 

void STDestory(ST* pst)
{
    assert(pst);
    free(pst->a); 
    pst->top=pst->capacity=0;
}
//入栈 出栈
void STPush(ST* pst,STDataType x)
{
    assert(pst);
    //扩容
    if(pst->top==pst->capcity)
    {
       int newCapcity=pst->capcity==0?4:pst->capcity*2;
       STDataType* tmp=realloc(pst->a,newCapcity*sizeof(STDataType));
       if(tmp==NULL)
       {
           perror("realloc fail");
           return;
       }
       pst->a=tmp;
       pst->capcity=newCapcity; 
       pst->a[pst->top]=x;
       pst->top++;
}
void STPop(ST* pst)
{
  assert(pst);
  pst->top--;
}
STDataType STTop(ST* pst)//获取栈顶元素
{
  assert(pst);
  assert(pst->top>0);
  return pst->a[pst->top-1];
}
bool STEmpty(ST* pst)
{
  assert(pst);
  return pst->top==0;
}
int STSize(ST* pst)
{
   assert(pst);
  return pst->top;
}
代码语言:javascript
复制
int main()
{
   ST s;
   STInit(&s);
   STPush(&s,1);
   STPush(&s,2);
   STPush(&s,3);
   while(!STEmpty(&s))
   {
      printf("%d ",STTop(&s);
      STPop(&s);
   }
  STDestory(&s);
}

我们应该知道,top应该指向栈顶,还是栈顶的下一个元素呢?top等于0是有数据还是没数据呢。所以当栈里面没有元素的时候,top应该指向-1。

那么我们的初始化可以改成这样:

代码语言:javascript
复制
void STInit(ST* pst)
{
    assert(pst);
    pst->a=NULL;
    pst->top=0;//top指向栈顶数据的下一个位置
//top指向栈顶数据 pst->top=-1;
    pst->capcity=0;
}

20. 有效的括号 - 力扣(LeetCode)

第一步:左括号入栈,第二步:出栈顶的左括号判断和右括号是否匹配,如果匹配,继续,如果不匹配,终止。

代码语言:javascript
复制
bool isValid(char* s) {
   ST st;
   STInit(&st);
   while(*s)
   {
    if(*s=='('||*s=='['||*s=='{')//左括号入栈
    {
        STPush(st,*s);
    }
    else//右括号取栈顶的左括号尝试匹配
    {
        if(STEmpty(&st))
        {
           return false;
        }
        char top=STTop(&st);
        STPop(&st);
        if((top=='('&&*s!=')')
        ||(top=='{'&&*s!='}')
        (top=='('&&*s!=')'))//不匹配
        {
            return false;
        }
    }
    ++s;
   }
//如果栈不为空,说明左括号比右括号多,数量不匹配
   bool ret=STEmpty(&st);
   STDestory(&st);
   return ret;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档