目录
题目:
原理:
结构体MyStack
出栈void myStackPop(MyStack* obj)
入栈void myStackPush(MyStack* obj, int x)
读取栈顶元素int myStackTop(MyStack* obj)
判断栈空bool myStackEmpty(MyStack* obj)
销毁栈void myStackFree(MyStack* obj)
整体结果:
题目:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。
int pop()
移除并返回栈顶元素。
int top()
返回栈顶元素。
boolean empty()
如果栈是空的,返回 true
;否则,返回 false
。
原理:
结构体MyStack
定义了两个队列,原因在出栈中。
出栈void myStackPop(MyStack* obj)
这里通过队列实现栈,队列满足先进先出相当于上面图中3会先出来了,但出栈应该是1先出,这里通过创建两个单链表队列q1,q2,当一个队列中出队到只剩下一个结点时,这个时候再出队,就是栈顶的结点,把出队的结点放在另一个队列中,下一次要出栈,就重复刚才的操作(即将非空队列中的n-1个结点出队,放在空队列中,出队最后剩余的那一个结点)。
入栈void myStackPush(MyStack* obj, int x)
入栈和入队一样都是从队尾进入,所以这里只需要找到非空队列,进行入队操作即可。
读取栈顶元素int myStackTop(MyStack* obj)
首先要寻找,这两个队列中哪一个有结点(即非空),找到后,利用队列读取队尾元素的函数,直接可以实现读取栈顶元素。
判断栈空bool myStackEmpty(MyStack* obj)
这里需要判断两个队列都为空,则栈就为空。
销毁栈void myStackFree(MyStack* obj)
直接调用队列销毁函数,将两个队列销毁,再将obj释放掉,置为空。
整体结果:
//之前的代码为队列这个数据结构的实现,和之前文章的一样。
typedef int DataType;typedef struct QueueNode
{DataType data;struct QueueNode* next;
}QueueNode;typedef struct Queue
{QueueNode* phead;QueueNode* ptail;int size;
}Queue;bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead==NULL;
}void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}QueueNode* BuyNode(DataType x)
{QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}
void QueuePush(Queue* pq, DataType x)
{assert(pq);QueueNode*newnode= BuyNode(x);if (pq->phead ==NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = pq->ptail->next;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead == pq->ptail)
{free(pq->phead);pq->phead = pq->ptail = NULL;
}else
{QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;
}
pq->size--;
}DataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}DataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}int QueueSize(Queue* pq)
{return pq->size;
}void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
//typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* pst=(MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}}int myStackPop(MyStack* obj) {Queue*emp=&obj->q1;Queue*noemp=&obj->q2;if(QueueEmpty(&obj->q2)){emp=&obj->q2;noemp=&obj->q1;}while(QueueSize(noemp)>1){QueuePush(emp,QueueFront(noemp));QueuePop(noemp);}int top=QueueFront(noemp);QueuePop(noemp);return top;
}int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);obj=NULL;
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/