上一章实现了用栈来实现队列,这一次我们试试用队列来实现栈。
因为栈的特性是先进后出,队列是先进先出。
所以我们可以想到用两个队列,一个空队列,一个放数据,当我们入队的时候将数据直接放入非空队列,出队的时候将非空队列中除队尾外的所有元素放到空队列中,再出队尾即可。
如下图
如数据1,2,3,4
全部入队
模拟出栈
先将除队尾全部放到原来的空队列中
再进行出队,即可实现栈的特性先进后出
下面开始代码实现,
数据结构
typedef int DataType;
typedef struct QListNode
{
struct QListNode* next;
DataType data;
}QNode;
typedef struct Queue
{
QNode* front;
QNode* rear;
}Queue;
typedef struct {
Queue q1;
Queue q2;
} MyStack;
栈的实现部分就不再这里放了,之前几章有
初始化栈
MyStack* myStackCreate()
{
MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&stack->q1);
QueueInit(&stack->q2);
return stack;
}
入栈
void myStackPush(MyStack* obj, int x)
{
if(0 != QueueEmpty(&obj->q1))
{
QueuePush(&obj->q2, x);
}
else
{
QueuePush(&obj->q1, x);
}
}
将数据放入非空队列中
出栈
int myStackPop(MyStack* obj)
{
Queue* emptyq = &obj->q2, *noemptyq = &obj->q1;
DataType target;
if(0 != QueueEmpty(&obj->q1))
{
emptyq = &obj->q1;
noemptyq = &obj->q2;
}
while(QueueSize(noemptyq) > 1)
{
QueuePush(emptyq, QueueFront(noemptyq));
QueuePop(noemptyq);
}
target = QueueFront(noemptyq);
QueuePop(noemptyq);
return target;
}
将非空队列除最后一个元素外的全部元素放到空队列中
获取栈顶
int myStackTop(MyStack* obj)
{
Queue* noemptyq = &obj->q1;
if(0 != QueueEmpty(&obj->q1))
{
noemptyq = &obj->q2;
}
return QueueBack(noemptyq);
}
返回非空队列的队尾即最后一个元素,即为栈顶
判断栈是否为空
bool myStackEmpty(MyStack* obj)
{
if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2))
return true;
else
return false;
}
当两个队列全部为空时栈为空
销毁栈
void myStackFree(MyStack* obj)
{
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
obj = NULL;
}
这样我们就实现了用队列来实现栈
完整代码
typedef int DataType;
typedef struct QListNode
{
struct QListNode* next;
DataType data;
}QNode;
typedef struct Queue
{
QNode* front;
QNode* rear;
}Queue;
typedef struct {
Queue q1;
Queue q2;
} MyStack;
void QueueInit(Queue* q)
{
q->front = q->rear = NULL;
}
DataType QueueFront(Queue* q)
{
if(q->front != NULL)
return q->front->data;
else
return NULL;
}
DataType QueueBack(Queue* q)
{
if(q->rear != NULL)
return q->rear->data;
else
return NULL;
}
int QueueEmpty(Queue* q)
{
return q->front ? 0 : 1;
}
int QueueSize(Queue* q)
{
assert(q);
QNode* cur = q->front;
int count = 0;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
void QueuePush(Queue* q, DataType data)
{
assert(q);
QNode* node = (QNode*)malloc(sizeof(QNode));
node->data = data;
node->next = NULL;
if (q->rear)
{
q->rear->next = node;
q->rear = node;
}
else
{
q->front = q->rear = node;
}
}
void QueuePop(Queue* q)
{
assert(q);
if (NULL == q->front->next)
{
free(q->front);
q->front = q->rear = NULL;
}
else
{
QNode* next = q->front->next;
free(q->front);
q->front = next;
}
}
void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
q->front = q->rear = NULL;
}
MyStack* myStackCreate()
{
MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&stack->q1);
QueueInit(&stack->q2);
return stack;
}
void myStackPush(MyStack* obj, int x)
{
if(0 != QueueEmpty(&obj->q1))
{
QueuePush(&obj->q2, x);
}
else
{
QueuePush(&obj->q1, x);
}
}
int myStackPop(MyStack* obj)
{
Queue* emptyq = &obj->q2, *noemptyq = &obj->q1;
DataType target;
if(0 != QueueEmpty(&obj->q1))
{
emptyq = &obj->q1;
noemptyq = &obj->q2;
}
while(QueueSize(noemptyq) > 1)
{
QueuePush(emptyq, QueueFront(noemptyq));
QueuePop(noemptyq);
}
target = QueueFront(noemptyq);
QueuePop(noemptyq);
return target;
}
int myStackTop(MyStack* obj)
{
Queue* noemptyq = &obj->q1;
if(0 != QueueEmpty(&obj->q1))
{
noemptyq = &obj->q2;
}
return QueueBack(noemptyq);
}
bool myStackEmpty(MyStack* obj)
{
if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2))
return true;
else
return false;
}
void myStackFree(MyStack* obj)
{
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
obj = NULL;
}