题目链接: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算法,加油!