一、用栈实现队列:
题目描述:
请你仅使用两个栈实现先入先出队列。
队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;
否则,返回 false
说明:
你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
思路分析:
1、建立两个栈,pushST和popST。
2、进队列的数据全都进到pushST栈中,如下图所示。
3、出队列时,分为两种情况:
(1)popST为空时,将pushST栈顶的数据依次进到popST中,并弹出,直到pushST为空时结束。再将popST栈顶的数据弹出。
(2)popST不为空时,直接弹出popST的栈顶数据即可。
4、取队头时同理,只是不弹出。
代码实现:
typedef int STDateType;
typedef struct stack//栈用数组实现更简单一点
{
STDateType* a;
int size;
int capacity;
}stack;
void stackInit(stack* pst)
{
assert(pst);
pst->a = (STDateType*)malloc(sizeof(STDateType)*4);
pst->size = 0;
pst->capacity = 4;
}
void stackDestory(stack* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->size = pst->capacity = 0;
}
//入栈
void stackPush(stack* pst, STDateType x)
{
assert(pst);
if (pst->size == pst->capacity)
{
pst->capacity *= 2;
STDateType* tmp = (STDateType*)realloc(pst->a, sizeof(STDateType)*pst->capacity);
pst->a = tmp;
}
pst->a[pst->size] = x;
pst->size++;
}
//出栈
void stackPop(stack* pst)
{
assert(pst);
assert(pst->size > 0);
pst->size--;
}
int stackEmpty(stack* pst)//返回1是空,返回0是非空
{
assert(pst);
return pst->size == 0 ? 1 : 0;
}
//获取栈顶的数据
STDateType stackTop(stack* pst)
{
assert(pst);
assert(pst->size > 0);
return pst->a[pst->size - 1];
}
typedef struct {
stack pushST;
stack popST;
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
stackInit(&q->pushST);
stackInit(&q->popST);
return q;
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
stackPush(&obj->pushST, x);
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
int front = myQueuePeek(obj);//取队头
stackPop(&obj->popST);
return front;
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
if(!stackEmpty(&obj->popST))
{
return stackTop(&obj->popST);
}
else
{
while(!stackEmpty(&obj->pushST))
{
stackPush(&obj->popST,stackTop(&obj->pushST));
stackPop(&obj->pushST);
}
return stackTop(&obj->popST);
}
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
if(stackEmpty(&obj->pushST)&&stackEmpty(&obj->popST))
{
return true;
}
return false;
}
void myQueueFree(MyQueue* obj) {
stackDestory(&obj->pushST);
stackDestory(&obj->popST);
free(obj);
obj = NULL;
}
二、用队列实现栈:
题目描述:
使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
思路分析:
1、建立两个队列,q1和q2(假设q1不为空,q2为空)
2、入栈时将数据入到不为空的队列中。
3、出栈时,将队列q1中数据依次出队到队列q2中,并弹出,直到队列q1中剩一个数据。将该数据弹出即可。具体步骤如下图所示。
核心:总有一个队列是为空的。
4、获取栈顶的数据时,取不为空的那个队列的队尾即可。
代码实现:
//只有弹出数据的时候要借助两个队列,取栈顶元素的时候可以直接利用队尾指针即可
typedef char QDataType;
typedef struct queueNode
{
struct queueNode* next;
QDataType data;
}queueNode;
typedef struct queue
{
queueNode* head;
queueNode* tail;
}queue;
void queueInit(queue* pq)
{
assert(pq);
(pq)->head = NULL;
(pq)->tail = NULL;
}
void queueDestory(queue* pq)
{
assert(pq);
queueNode* cur = pq->head;
while (cur)
{
queueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
void queuePush(queue* pq, QDataType x)
{
assert(pq);
queueNode* newnode = (queueNode*)malloc(sizeof(queueNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void queuePop(queue* pq)
{
assert(pq);
assert(pq->head);
queueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
QDataType queueFront(queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
QDataType queueBack(queue* pq)
{
assert(pq);
assert(pq->tail);
return pq->tail->data;
}
int queueEmpty(queue* pq)//返回1是空,0是非空
{
if (pq->head == NULL)
{
return 1;
}
else return 0;
}
int queueSize(queue* pq)
{
assert(pq);
int size = 0;
queueNode* cur = pq->head;
while (cur != NULL)
{
size++;
cur = cur->next;
}
return size;
}
typedef struct {
queue q1;
queue q2;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStack* obj =(MyStack*)malloc(sizeof(MyStack));
queueInit(&obj->q1);
queueInit(&obj->q2);
return obj;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
if(!queueEmpty(&obj->q1))//将数据入到不为空的队列里
{
queuePush(&obj->q1,x);
}
else
{
queuePush(&obj->q2,x);
}
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
queue* empty = &obj->q1;
queue* nonEmpty = &obj->q2;
if(queueEmpty(&obj->q2))//如果q2为空
{
empty = &obj->q2;
nonEmpty = &obj->q1;
}
while(queueSize(nonEmpty) > 1)//对非空的队列操作
{
queuePush(empty,queueFront(nonEmpty));
queuePop(nonEmpty);
}
int top = queueFront(nonEmpty);
queuePop(nonEmpty);//把最后一个数据弹掉
return top;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
if(!queueEmpty(&obj->q1))
{
return queueBack(&obj->q1);
}
else//如果两者都为空,该题不会调用该接口
{
return queueBack(&obj->q2);
}
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
if(queueEmpty(&obj->q1)&&queueEmpty(&obj->q2))
{
return true;
}
return false;
}
void myStackFree(MyStack* obj) {
queueDestory(&obj->q1);
queueDestory(&obj->q2);
free(obj);
obj=NULL;
}