栈和队列的应用

1.有效的括号【https://leetcode-cn.com/problems/valid-parentheses/】

  利用栈解决问题,如果遇到括号的右边直接进行入栈;如果遇到左边的括号,取栈顶元素与之进行匹配,如果匹配成功让栈顶元素出栈,如果匹配不成功返回false;最后在判断完字符串中的所有元素后,如果栈为空返回true,否则返回false完成判断。

//栈的实现

#define LinkStackElemType char

typedef struct LinkStackNode

{

    LinkStackElemType data;

    struct LinkStackNode *link;

}LinkStackNode;

typedef struct LinkStack

{

    LinkStackNode *head;

}LinkStack;

void LinkStackInit(LinkStack *pst);

void LinkStackPush(LinkStack *pst, LinkStackElemType v);

void LinkStackPop(LinkStack *pst);

LinkStackElemType LinkStackTop(LinkStack *pst);

void LinkStackShow(LinkStack *pst);

bool LinkStackEmpty(LinkStack *pst)

{

    assert(pst != NULL);

    return pst->head == NULL;

}

void LinkStackInit(LinkStack *pst)

{

    assert(pst != NULL);

    pst->head = NULL;

}

void LinkStackPush(LinkStack *pst, LinkStackElemType v)

{

    assert(pst != NULL);

    LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));

    assert(s != NULL);

    s->data = v;

    //把节点头插

    s->link = pst->head;

    pst->head = s;

}

void LinkStackPop(LinkStack *pst)

{

    assert(pst != NULL);

    if(LinkStackEmpty(pst))

    {

        printf("栈已空,不能出栈.\n");

        return;

    }

    LinkStackNode *p = pst->head;

    pst->head = p->link;

}

LinkStackElemType LinkStackTop(LinkStack *pst)

{

    assert(pst != NULL);

    if(LinkStackEmpty(pst))

    {

        printf("栈已空,不能取栈顶元素.\n");

        return;

    }

    return pst->head->data;

}

void LinkStackShow(LinkStack *pst)

{

    assert(pst != NULL);

    LinkStackNode *p = pst->head;

    while(p != NULL)

    {

        printf("%d\n", p->data);

        p = p->link;

    }

}

/

bool isValid(char * s){

    assert(s!=NULL);

    LinkStack pst;

    LinkStackInit(&pst);

    while(*s!='\0')

    {

        if(*s=='('||*s=='['||*s=='{')

            LinkStackPush(&pst,*s);

        else

        {

            if(LinkStackEmpty(&pst))

                return false;

            char a=LinkStackTop(&pst);

            if((a=='('&&*s==')')||(a=='['&&*s==']')||(a=='{'&&*s=='}'))

                 LinkStackPop(&pst);

            else

                return false;

        }

        s++;

    }

    if(LinkStackEmpty(&pst))

        return true;

    return false;

}

2.用队列实现栈 【https://leetcode-cn.com/problems/implement-stack-using-queues/】

  用队列实现栈至少需要两个队列,入栈时需要找出为空的队列进行入队即入栈;出栈时需要分别找出为空的队列和不为空的队列,将不为空的队列中的元素进行出队,将出队的元素在为空的队列中进行入队,最后一个元素不进行入队,完成了出栈。

//队列实现

#define LinkQueueElemType int

typedef struct LinkQueueNode

{

    LinkQueueElemType data;

    struct LinkQueueNode *link;

}LinkQueueNode;

typedef struct LinkQueue

{

    LinkQueueNode *front;

    LinkQueueNode *rear;

}LinkQueue;

bool LinkQueueEmpty(LinkQueue *pq)

{

    assert(pq != NULL);

    return pq->front == NULL;

}

void LinkQueueInit(LinkQueue *pq);

void LinkQueuePush(LinkQueue *pq, LinkQueueElemType v);

void LinkQueuePop(LinkQueue *pq);

void LinkQueueShow(LinkQueue *pq);

LinkQueueElemType LinkQueueFront(LinkQueue *pq);

LinkQueueElemType LinkQueueBack(LinkQueue *pq);

/

void LinkQueueInit(LinkQueue *pq)

{

    assert(pq != NULL);

    pq->front = pq->rear = NULL;

}

void LinkQueuePush(LinkQueue *pq, LinkQueueElemType v)

{

    assert(pq != NULL);

    LinkQueueNode *s = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));

    assert(s != NULL);

    s->data = v;

    s->link = NULL;

    if(pq->rear == NULL)

        pq->front = pq->rear = s;

    else

    {

        pq->rear->link = s;

        pq->rear = s;

    }

}

void LinkQueuePop(LinkQueue *pq)

{

    assert(pq != NULL);

    if(LinkQueueEmpty(pq))

    {

        printf("队列已空,不能出队.\n");

        return;

    }

    LinkQueueNode *p = pq->front;

    if(pq->front == pq->rear)

        pq->rear = NULL;

    pq->front = p->link;

    free(p);

}

void LinkQueueShow(LinkQueue *pq)

{

    assert(pq != NULL);

    LinkQueueNode *p = pq->front;

    while(p != NULL)

    {

        printf("%d ", p->data);

        p = p->link;

    }

    printf("\n");

}

LinkQueueElemType LinkQueueFront(LinkQueue *pq)

{

    assert(pq != NULL);

    assert(!LinkQueueEmpty(pq));

    return pq->front->data;

}

LinkQueueElemType LinkQueueBack(LinkQueue *pq)

{

    assert(pq != NULL);

    assert(!LinkQueueEmpty(pq));

    return pq->rear->data;

}

//

//用队列实现栈

typedef struct {

    LinkQueue q1;

    LinkQueue q2;

} MyStack;

MyStack* myStackCreate() {

    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));

    LinkQueueInit(&pst->q1);

    LinkQueueInit(&pst->q2);

    return pst;

}

void myStackPush(MyStack* obj, int x) {

    LinkQueue *noempty;

    if(LinkQueueEmpty(&obj->q1))

        noempty=&obj->q2;

    if(LinkQueueEmpty(&obj->q2))

        noempty=&obj->q1;

    LinkQueuePush(noempty,x);

}

int myStackPop(MyStack* obj) {

    LinkQueue *noempty,*empty;

    int val;

    if(LinkQueueEmpty(&obj->q1))

    {

        noempty=&obj->q2;

        empty=&obj->q1;

    }

    if(LinkQueueEmpty(&obj->q2))

    {

        noempty=&obj->q1;

        empty=&obj->q2;

    }

    while(!LinkQueueEmpty(noempty))

    {

        val=LinkQueueFront(noempty);

        LinkQueuePop(noempty);

        if(!LinkQueueEmpty(noempty))

            LinkQueuePush(empty,val);

    }

    return val;

}

int myStackTop(MyStack* obj) {

    LinkQueue *noempty,*empty;

    int val;

    if(LinkQueueEmpty(&obj->q1))

    {

        noempty=&obj->q2;

        empty=&obj->q1;

    }

    if(LinkQueueEmpty(&obj->q2))

    {

        noempty=&obj->q1;

        empty=&obj->q2;

    }

    while(!LinkQueueEmpty(noempty))

    {

        val=LinkQueueFront(noempty);

        LinkQueuePop(noempty);

        LinkQueuePush(empty,val);

    }

    return val;

}

bool myStackEmpty(MyStack* obj) {

    return LinkQueueEmpty(&obj->q1)&&LinkQueueEmpty(&obj->q2);

}

void myStackFree(MyStack* obj) {

    free(obj);

}

3.用栈实现队列【https://leetcode-cn.com/problems/implement-queue-using-stacks/】

  用栈实现队列,至少需要两个栈来完成。用栈1只进行入队操作即对栈1进行元素入栈;要进行出队时,将栈1中的元素出栈,在栈2中进行入栈,最后将栈2中栈顶的元素进行出栈,达到了出队的效果。

//栈实现

#define LinkStackElemType int  

typedef struct LinkStackNode

{

    LinkStackElemType data;

    struct LinkStackNode *link;

}LinkStackNode;

typedef struct LinkStack

{

    LinkStackNode *head;

}LinkStack;

void LinkStackInit(LinkStack *pst);

void LinkStackPush(LinkStack *pst, LinkStackElemType v);

void LinkStackPop(LinkStack *pst);

LinkStackElemType LinkStackTop(LinkStack *pst);

void LinkStackShow(LinkStack *pst);

bool LinkStackEmpty(LinkStack *pst)

{

    assert(pst != NULL);

    return pst->head == NULL;

}

void LinkStackInit(LinkStack *pst)

{

    assert(pst != NULL);

    pst->head = NULL;

}

void LinkStackPush(LinkStack *pst, LinkStackElemType v)

{

    assert(pst != NULL);

    LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));

    assert(s != NULL);

    s->data = v;

    //把节点头插

    s->link = pst->head;

    pst->head = s;

}

void LinkStackPop(LinkStack *pst)

{

    assert(pst != NULL);

    if(LinkStackEmpty(pst))

    {

        printf("栈已空,不能出栈.\n");

        return;

    }

    LinkStackNode *p = pst->head;

    pst->head = p->link;

}

LinkStackElemType LinkStackTop(LinkStack *pst)

{

    assert(pst != NULL);

    if(LinkStackEmpty(pst))

    {

        printf("栈已空,不能取栈顶元素.\n");

        return;

    }

    return pst->head->data;

}

void LinkStackShow(LinkStack *pst)

{

    assert(pst != NULL);

    LinkStackNode *p = pst->head;

    while(p != NULL)

    {

        printf("%d\n", p->data);

        p = p->link;

    }

}

//用栈实现队列

typedef struct {

    LinkStack q1;

    LinkStack q2;

} MyQueue;

MyQueue* myQueueCreate() {

    MyQueue *pq=(MyQueue*)malloc(sizeof(MyQueue));

    LinkStackInit(&pq->q1);

    LinkStackInit(&pq->q2);

    return pq;

}

bool myQueueEmpty(MyQueue* obj) {

     if(LinkStackEmpty(&obj->q1)&&LinkStackEmpty(&obj->q2))

        return true;

    return false;

}

void myQueuePush(MyQueue* obj, int x) {

    LinkStackPush(&obj->q1,x);

}

int myQueuePop(MyQueue* obj) {

    int val;

    if(LinkStackEmpty(&obj->q2))

    {

        while(!LinkStackEmpty(&obj->q1))

        {

            val=LinkStackTop(&obj->q1);

            LinkStackPop(&obj->q1);

            LinkStackPush(&obj->q2,val);

        }

    }

    val=LinkStackTop(&obj->q2);

    LinkStackPop(&obj->q2);

    return val;

}

int myQueuePeek(MyQueue* obj) {

    int val;

    if(LinkStackEmpty(&obj->q2))

    {

        while(!LinkStackEmpty(&obj->q1))

        {

            val=LinkStackTop(&obj->q1);

            LinkStackPop(&obj->q1);

            LinkStackPush(&obj->q2,val);

        }

    }

    val=LinkStackTop(&obj->q2);

    return val;

}

void myQueueFree(MyQueue* obj) {

    free(obj);

}

4设计循环队列【https://leetcode-cn.com/problems/design-circular-queue/】

    设计循环队列主要在于让数组下标循环起来。front首元素下标,rear尾元素的下一个元素的坐标(此时未存放元素),capacity空间大小。判满条件(obj->rear+1)%obj->capacity==obj->front(obj为该队列)。判空条件obj->front==obj->rear。进行入队时第一步放入数据obj->base[obj->rear]=value; 第二部尾指针rear(在这里就是数组尾元素下标)指向下一个元素位置obj->rear=(obj->rear+1)%obj->capacity;。进行出队时头指针front(在这里就是数组首元素下标)指向下一个位置obj->front=(obj->front+1)%obj->capacity;。

//循环队列的实现

typedef struct {

    int *base;//数组首元素地址

    int front;

    int rear;

    int capacity;

} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {

    MyCircularQueue *pq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));

    pq->base = (int*)malloc(sizeof(int) * (k+1));

    pq->front=pq->rear=0;

    pq->capacity=k+1;

    return pq;

}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

    return obj->front==obj->rear;

}

bool myCircularQueueIsFull(MyCircularQueue* obj) {

    return ((obj->rear+1)%obj->capacity==obj->front);

}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {

    if(myCircularQueueIsFull(obj))

        return false;

    obj->base[obj->rear]=value;

    obj->rear=(obj->rear+1)%obj->capacity;

    return true;

}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {

    if(myCircularQueueIsEmpty(obj))

        return false;

    obj->front=(obj->front+1)%obj->capacity;

    return true;

}

int myCircularQueueFront(MyCircularQueue* obj) {

    if(myCircularQueueIsEmpty(obj))

        return -1;

    return obj->base[obj->front];

}

int myCircularQueueRear(MyCircularQueue* obj) {

    if(myCircularQueueIsEmpty(obj))

        return -1;

    return obj->base[(obj->rear-1+obj->capacity)%obj->capacity];

}

void myCircularQueueFree(MyCircularQueue* obj) {

    free(obj->base);

    free(obj);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值