栈------------------------------------------------------------------------------------
// 一种特殊的线性表,只允许固定一端进行插入和删除元素操作
// 进行插入删除操作的一段称为栈顶,另一端称为栈底
// 栈中的元素遵循后进先出LIfO
// 压栈:栈的插入操作,入栈数据在栈顶
// 出栈:栈的删除操作,出栈数据也在栈顶
//
// 数组栈:头为栈底,尾为栈顶,尾插尾删(推荐优先)
//
// 链式栈:头为栈底,尾为栈顶,尾插尾删,双链表
// 头为栈顶,尾为栈底,头插头删,单链表
#include<assert.h>
typedef char STDateType;
//创建一个数组栈
typedef struct Stack
{
STDateType* a;
int top;//栈顶,作为访问数组栈成员的下标来引用
int capacity;//容量
}ST;
//初始化
void StackInit(ST * ps);
//插入
void StackPush(ST* ps, STDateType x);
//删除
void StackPop(ST* ps);
//取栈顶的数据
STDateType StackTop(ST* ps);
//栈的大小
int StackSize(ST* ps);
//判断栈是否为空
bool StackEmpty(ST* ps);
//销毁
void StackDestroy(ST* ps);
//初始化
void StackInit(ST* ps)
{
//assert(ps);
ps->a = NULL;
ps->capacity = 0;
//初始化时,top为0,top指向栈顶数据的下一个,x插入后再top++
ps->top = 0;
//初始化时,top为-1,top指向栈顶数据,先top++,再插入
//ps->top = -1;
}
//销毁
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//插入
void StackPush(ST* ps, STDateType x)
{
assert(ps);
//增容
if (ps->top == ps->capacity)
{
//先增容
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
//再开辟空间
STDateType* tmp = (STDateType*)realloc(ps->a, sizeof(STDateType) * newCapacity);
if (tmp == NULL)//开辟失败
{
printf("realloc fail!");
exit(-1);
}
//指向增容后的空间
ps->a = tmp;
ps->capacity = newCapacity;
}
//解引用栈顶top为下标的a,赋值
ps->a[ps->top] = x;
//栈顶top往后走
ps->top++;
}
//删除
void StackPop(ST* ps)
{
assert(ps);
//断言栈内元素不为空
//assert(ps->top > 0);
assert(!StackEmpty(ps));
//删除
ps->top--;
}
//取栈顶的数据
STDateType StackTop(ST* ps)
{
assert(ps);
//断言栈内元素不为空
//assert(ps->top > 0);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
//栈的大小
int StackSize(ST* ps)
{
assert(ps);
//top指向栈顶数据的下一个,即为数组大小
return ps->top;
}
//判断栈是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
//等于0返回真,否则返回假
return ps->top == 0;
}
//判断是否为(){}[]相匹配
bool isValid(char* s ) {
//建立数组栈
ST st;
//初始化
StackInit(&st);
//是左括号则入栈
while (*s)
{
if (*s == '(' || *s == '{' || *s == '[')
{
StackPush(&st, *s);
s++;
}
//是右括号,则出栈,与右括号进行匹配
else
{
//遇到右括号,栈里为空,没有左括号来匹配
if (StackEmpty(&st))
{
return false;
}
STDateType top = StackTop(&st);
StackPop(&st);
if ((top != '(' && *s == ')') ||
(top != '[' && *s == ']') ||
(top != '{' && *s == '}'))
{
StackDestroy(&st);
return false;
}
else
{
s++;
}
}
}
//如果栈不为空,说明还有未匹配的左括号
bool ret = StackEmpty(&st);
StackDestroy(&st);
return ret;
}
//用两个栈实现队列---------------------------------------------------------------------
//创建两个数组栈
typedef struct
{
ST PushST;
ST PopST;
}MyQeuque;
//队列初始化
MyQeuque* MyQeuqueCreate()
{
//开辟一个队列
MyQeuque* q = (MyQeuque*)malloc(sizeof(MyQeuque));
//初始化
StackInit(&q->PushST);
StackInit(&q->PopST);
return q;
}
//入队列操作
void myQuequePush(MyQeuque* obj, int x)
{
//将数据压栈操作存入pushST中
StackPush(&obj->PushST, x);
}
//出队列操作
int myQuequePop(MyQeuque* obj)
{
//如果PopST为空
if (!StackEmpty(&obj->PopST))
{
while(StackEmpty(&obj->PushST))
{
//将pushST中的数据存入popST中,再取top数据,就可以实现先进先出的队列特性
StackPush(&obj->PopST, StackTop(&obj->PushST));
//PushST再出栈操作-删除
StackPop(&obj->PushST);
//直到PushST的数据全部录入PopST中
}
}
//取出栈顶数据
int front = StackTop(&obj->PopST);
//PopST再出栈操作-删除,方便下次出栈。达到出队列的效果
StackPop(&obj->PopST);
}
int myQuequePeek(MyQeuque* obj)
{
//如果PopST为空
if (!StackEmpty(&obj->PopST))
{
while (StackEmpty(&obj->PushST))
{
//将pushST中的数据存入popST中,再取top数据,就可以实现先进先出的队列特性
StackPush(&obj->PopST, StackTop(&obj->PushST));
//PushST再出栈操作-删除
StackPop(&obj->PushST);
//直到PushST的数据全部录入PopST中
}
}
return StackTop(&obj->PopST);
}
//判断是否为空
bool myQuequeEmpty(MyQeuque* obj)
{
return StackEmpty(&obj->PopST) && StackEmpty(&obj->PushST);
}
//销毁
void myQuequeFree(MyQeuque* obj)
{
//先销毁栈
StackDestroy(&obj->PushST);
StackDestroy(&obj->PopST);
//再释放obj
free(obj);
}