现在是个激动人心的时刻,因为我们来到了栈和队列的章节。
栈是一种特殊的线性表,只允许在一端进行插入和删除操作。进入数据插入和删除的一端叫作栈顶,另一端称为栈底。具有后进先出的特点。
压栈:数据的插入操作叫作进栈/入栈/压栈。
出栈:栈的删除操作叫作出栈,出栈也在栈顶。
栈的实现可以用数组或者线性表实现,相对而言,数组实现更优,因为数组在尾上插入的代价较小。
队列的表示和实现:
队列只允许在一端进行插入操作,在另一端进行删除操作。具有先进先出的特点。
入队列:进入插入操作的一端为队尾。
出队列:进行删除操作的一端为队头。
关于原地扩容和异地扩容:
异地扩容就是在新的地方开辟一个新的空间。
以上代码测试出如果是一样的,那么就是原地扩容,如果不一样,就是异地扩容。
此时地址是一样的。但是当我们把扩容的空间增大,地址不一样。
数据都在内存里,在堆上。
不会直接访问数据。在缓存,就叫做缓存命中。如果不在缓存,就叫作不命中,要把数据从内存加载到缓存,再访问。
实现静态的栈:
#define N 10
struct Stack
{int a[N];
};
动态的栈:
Stack.h
#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
#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;
}
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。
那么我们的初始化可以改成这样:
void STInit(ST* pst)
{assert(pst);pst->a=NULL;pst->top=0;//top指向栈顶数据的下一个位置
//top指向栈顶数据 pst->top=-1;pst->capcity=0;
}
20. 有效的括号 - 力扣(LeetCode)
第一步:左括号入栈,第二步:出栈顶的左括号判断和右括号是否匹配,如果匹配,继续,如果不匹配,终止。
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;
}