题目:请你仅使用两个队列实现一个后入先出的的栈,并支持普通栈的全部四种操作(push,top,pop和empty)。
实现MyStack类:
- void push (int x)将元素x压入栈顶。
- int pop () 移除并返回栈顶元素。
- int top () 返回栈顶元素。
- boolean empty () 如果栈是空的,返回true;否则,返回false。
思路:
1、两个队列,一个队列有数据,一个队列没数据
2、入数据:往不为空的队列里放
3、出数据:不为空的队列前size-1个倒入另一个队列,pop掉最后剩下的一个数据
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
} QueueNode;
// 对于队列来说就好有两个指针,分别指向队列的头和尾
typedef struct Queue
{
QueueNode* phead;
QueueNode* ptail;
} Queue;
//队列初始化
void QueueInit(Queue* pq);
//队列的销毁
void QueueDesTroy(Queue* pq);
// 入数据,队尾
void QueuePush(Queue* pq, QDataType x);
// 出数据,队头
void QueuePop(Queue* pq);
bool QueueEmpty(Queue* pq);
size_t QueueSize(Queue* pq);
// 取队头数据
QDataType QueueFront(Queue* pq);
// 取队尾数据
QDataType QueueBack(Queue* pq);
void QueueInit(Queue* pq) {
assert(pq);
pq->phead = pq->ptail = NULL;
}
void QueueDesTroy(Queue* pq) {
assert(pq);
QueueNode* cur = pq->phead;
while (cur) {
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
}
//队列入数据
void QueuePush(Queue* pq, QDataType x) {
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL) {
printf("malloc fail!\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
// 如果是第一个元素,队列为空
if (pq->ptail == NULL) {
pq->phead = pq->ptail = newnode;
} else {
pq->ptail->next = newnode;
pq->ptail = pq->ptail->next;
}
}
bool QueueEmpty(Queue* pq) {
assert(pq);
return pq->phead == NULL && pq->ptail == NULL;
}
//处理队列只有一个节点时
void QueuePop(Queue* pq) {
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* next = pq->phead->next;
// 如果队列只有一个节点 (phead = ptail = node)
// 出队列中phead释放时,ptail变成了一个野指针
if (pq->ptail == pq->phead) {
pq->ptail = NULL;
}
free(pq->phead);
pq->phead = next;
}
// 如果需要频繁获取队列大小,可以和Queue中加一个size记录数
size_t QueueSize(Queue* pq) {
assert(pq);
QueueNode* cur = pq->phead;
size_t size = 0;
while (cur != NULL) {
size++;
cur = cur->next;
}
return size;
}
// 取队头数据
QDataType QueueFront(Queue* pq) {
assert(pq);
assert(!QueueEmpty(pq));
return pq->phead->data;
}
// 取队尾数据
QDataType QueueBack(Queue* pq) {
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
//创建栈
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* psl = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&psl->q1);
QueueInit(&psl->q2);
return psl;
}
void myStackPush(MyStack* obj, int x) {
assert(obj);
// 往不为空的队列里放数据
if (!QueueEmpty(&obj->q1)) {
QueuePush(&obj->q1, x);
} else {
QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
assert(obj);
// 把不为空的队列,把前size-1个数据倒入另一个队列中
Queue* empQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if (!QueueEmpty(empQ)) {
nonemptyQ = &obj->q1;
empQ = &obj->q2;
}
while (QueueSize(nonemptyQ) > 1) {
// 倒数据
QueuePush(empQ, QueueFront(nonemptyQ));
QueuePop(nonemptyQ);
}
int top = QueueFront(nonemptyQ);
QueuePop(nonemptyQ);
return top;
}
int myStackTop(MyStack* obj) {
assert(obj);
if (!QueueEmpty(&obj->q1)) {
return QueueBack(&obj->q1);
} else {
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack*obj){
assert(obj);
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2)
}
void myStackFree(MyStack*obj){
assert(obj);
QueueDesTroy(&obj->q1);
QueueDesTroy(&obj->q1);
free(obj);
}