栈的操作--数组栈判断有效括号序列--两个栈实现队列--题解

栈------------------------------------------------------------------------------------
// 一种特殊的线性表,只允许固定一端进行插入和删除元素操作
// 进行插入删除操作的一段称为栈顶,另一端称为栈底
// 栈中的元素遵循后进先出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);
}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值