队列实现栈
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列是先进先出
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈是后进先出
栈顶:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
栈底:栈的删除操作叫做出栈。出数据也在栈顶
我们选择链表进行操作
为什么不用数组呢?
对于队列我们要进行入队和出队的操作,如果是使用数组来实现的话,那么我们所需要的时间开销就很大,需要不停的挪动数据。但是反过来看链表的话,就方便了许多,不需要频繁的挪动数据,入队出队时的操作都显得相对容易和快速
我们的思路就是:创建两个队列,保存一个队列存数据不为空,另一个队列为空。
- pop接口:
把非空队列的前n-1个元素转移到空队列中,再把空队列中的最后一个元素pop掉。
这里我借用大佬的动图给你们演示一下。
-
push接口:
直接在非空队列插入即可
q1为空就在q1插入
q2为空就在q2插入 -
top接口:
判断哪个队列为非空队列,直接返回非空队列的队尾节点 -
empty接口:
两个队列都为空就为true
代码实现
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
return QueuePush(&obj->q1, x);
}
else
{
return QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
//设置非空和空队列
Queue* Qempty = &obj->q1;
Queue* noQempty = &obj->q2;
if(!QueueEmpty(&obj->q1))
{
noQempty = &obj->q1;
Qempty = &obj->q2;
}
//把非空中前n-1个元素push到空中
while(QueueSize(noQempty) > 1)
{
//转移
QueuePush(Qempty, QueueFront(noQempty));
//删除
QueuePop(noQempty);
}
int top = QueueFront(noQempty);
QueuePop(noQempty);
return top;
}
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1))
{
return QueueTail(&obj->q1);
}
else
{
return QueueTail(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
整体代码:
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
typedef struct QueueList
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueTail(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
pq->size = 0;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
//尾插
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL)
{
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
}
pq->size--;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
QDataType QueueTail(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
///
//队列实现栈,上面是队列的实现
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
return QueuePush(&obj->q1, x);
}
else
{
return QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
//设置非空和空队列
Queue* Qempty = &obj->q1;
Queue* noQempty = &obj->q2;
if(!QueueEmpty(&obj->q1))
{
noQempty = &obj->q1;
Qempty = &obj->q2;
}
//把非空中前n-1个元素push到空中
while(QueueSize(noQempty) > 1)
{
//转移
QueuePush(Qempty, QueueFront(noQempty));
//删除
QueuePop(noQempty);
}
int top = QueueFront(noQempty);
QueuePop(noQempty);
return top;
}
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1))
{
return QueueTail(&obj->q1);
}
else
{
return QueueTail(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
力扣链接:队列实现栈