代码随想录算法训练营第十天| 232.用栈实现队列 、225. 用队列实现栈

题目链接:232.用栈实现队列

当我看到这一题的时候,心想出题人是不是有猫病。。。。。好好的队列不用,非要用两个栈去模拟队列,但转头一想,用两个栈实现队列这件事貌似没有那么容易。栈(LIFO)是先进后出的数据结构,而队列(FIFO)是先进先出的数据结构,因此我们将一个栈中的元素如果能够反转,再按照栈先进后出的规则即可模拟队列。反转这件事可以借助将一个栈中的元素全都pop到另一个栈来实现,因此解题思路就有了,具体代码如下所示:

typedef struct stack {
    int val;
    struct stack *next;
}linknode, *linkstack;

typedef struct {
    linkstack first_stack;
    linkstack second_stack;
} MyQueue;

MyQueue* myQueueCreate() {
    MyQueue *queue = (MyQueue *)malloc(sizeof(MyQueue));
    queue->first_stack = (linkstack)malloc(sizeof(linknode));
    queue->second_stack = (linkstack)malloc(sizeof(linknode));
    queue->first_stack->next = NULL;
    queue->second_stack->next = NULL;
    memset(queue->first_stack, 0, sizeof(linknode));
    memset(queue->second_stack, 0, sizeof(linknode));
    return queue;
}

void myQueuePush(MyQueue* obj, int x) {
    linkstack p = (linkstack)malloc(sizeof(linknode));
    p->val = x;
    p->next = obj->first_stack->next;
    obj->first_stack->next = p;
}

int myQueuePop(MyQueue* obj) {
    if (obj->second_stack->next == NULL) {
        linkstack tmp = obj->first_stack->next;
        while (tmp != NULL) {
            obj->first_stack->next = obj->first_stack->next->next;
            tmp->next = obj->second_stack->next;
            obj->second_stack->next = tmp;
            tmp = obj->first_stack->next;
        }
    }
    int i = obj->second_stack->next->val;
    linkstack p = obj->second_stack->next;
    obj->second_stack->next = obj->second_stack->next->next;
    free(p);
    return i;
}

int myQueuePeek(MyQueue* obj) {
    if (obj->second_stack->next == NULL) {
        linkstack tmp = obj->first_stack->next;
        while (tmp != NULL) {
            obj->first_stack->next = obj->first_stack->next->next;
            tmp->next = obj->second_stack->next;
            obj->second_stack->next = tmp;
            tmp = obj->first_stack->next;
        }
    }
    return obj->second_stack->next->val;;
}

bool myQueueEmpty(MyQueue* obj) {
    return ((obj->first_stack->next == NULL) && (obj->second_stack->next == NULL)) ? true:false;
}

void myQueueFree(MyQueue* obj) {
    linkstack tmp = obj->first_stack;
    linkstack i;
    while (tmp != NULL) {
        i = tmp->next;
        free(tmp);
        tmp = i;
    }
    tmp = obj->second_stack;
    while (tmp != NULL) {
        i = tmp->next;
        free(tmp);
        tmp = i;
    }
}

题目链接:225. 用队列实现栈

我们知道队列先进先出,所以最后一个进的元素最后一个出。当我们将队列的数据弹出到只剩一个时,再次弹出的数据我们认为他才算是真正pop就可以了,执之前pop的数据全都push到第二个队列,pop完最后一个元素后,再将第二个队列的元素按照FIFO的形式push到第一个队列即可模拟栈,具体代码给出如下:

typedef struct queue {
    int val;
    struct queue *next;
}queuenode, *queuelink;

typedef struct {
    queuelink first_queue;
    queuelink second_queue;
} MyStack;

MyStack* myStackCreate() {
    MyStack *stack =(MyStack *)malloc(sizeof(MyStack));
    stack->first_queue = (queuelink)malloc(sizeof(queuenode));
    stack->second_queue = (queuelink)malloc(sizeof(queuenode));
    memset(stack->first_queue, 0, sizeof(queuenode));
    memset(stack->second_queue, 0, sizeof(queuenode));
    return stack;
}

void myStackPush(MyStack* obj, int x) {
    queuelink node = (queuelink)malloc(sizeof(queuenode));
    node->val = x;
    node->next = NULL;
    queuelink tmp = obj->first_queue;
    while (tmp->next != NULL)
        tmp = tmp->next;
    tmp->next = node;
}

int myStackPop(MyStack* obj) {
    queuelink tmp = obj->second_queue;
    if (obj->first_queue->next == NULL) {
        return 0;
    }
    if (obj->first_queue->next != NULL && obj->first_queue->next->next == NULL) {
        int i = obj->first_queue->next->val;
        queuelink tmp = obj->first_queue->next;
        obj->first_queue->next = NULL;
        free(tmp);
        return i;
    }
    while (obj->first_queue->next->next != NULL) {
        tmp->next = obj->first_queue->next;
        obj->first_queue->next = obj->first_queue->next->next;
        tmp = tmp->next;
    }
    tmp->next = NULL;
    int i = obj->first_queue->next->val;
    free(obj->first_queue->next);
    tmp = obj->first_queue;
    while (obj->second_queue->next != NULL) {
        tmp->next = obj->second_queue->next;
        tmp = tmp->next;
        obj->second_queue->next = obj->second_queue->next->next;
    }
    tmp->next = NULL;
    obj->second_queue->next = NULL;
    return i;
}

int myStackTop(MyStack* obj) {
    queuelink tmp = obj->first_queue;
    while (tmp->next != NULL)
        tmp = tmp->next;
    return tmp->val;
}

bool myStackEmpty(MyStack* obj) {
    return (obj->first_queue->next == NULL) ? true:false;
}

void myStackFree(MyStack* obj) {
    queuelink tmp = obj->first_queue;
    while (tmp != NULL) {
        queuelink i = tmp->next;
        free(tmp);
        tmp = i;
    }

    tmp = obj->second_queue;
    while (tmp != NULL) {
        queuelink i = tmp->next;
        free(tmp);
        tmp = i;
    }
}

今天的题目看上去简单,实际写的时候一定要注意细节,比如到底是哪个栈或者队列pop元素,以及指针用完后要free掉等细节。明天补一下第九天的内容-KMP算法,加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值