在数据结构中,栈和队列是两种非常基础且重要的数据结构。栈遵循后进先出(LIFO)的原则,而队列遵循先进先出(FIFO)的原则。本文将介绍如何使用队列来实现栈,以及如何使用栈来实现队列,并给出相应的代码实现。
相关OJ题 225. 用队列实现栈 - 力扣(LeetCode)
为了使用队列实现栈,我们可以使用两个队列 q1
和 q2
。在入栈操作时,我们将元素插入到非空的队列中;在出栈操作时,我们将非空队列中的元素除了最后一个元素外,全部移动到另一个空队列中,然后弹出最后一个元素。
以下是使用队列实现栈的代码:
#include
#include
#include
#include
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* ptail;
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 QueueBack(Queue* pq);
// 队列大小
int QueueSize(Queue* pq);
// 判空
bool QueueEmpty(Queue* pq);
// 初始化与销毁队列
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while(cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
// 队尾插入
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if(newnode == NULL)
{
perror("malloc fail!");
return;
}
newnode->next = NULL;
newnode->val = x;
if(pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
// 队头删除
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
// 一个节点
if(pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else // 多个节点
{
QNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
pq->size--;
}
// 取队头和队尾的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->val;
}
// 队列大小
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
// 判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return 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* Empty = &obj->q1;
Queue* nonEmpty = &obj->q2;
if(!QueueEmpty(&obj->q1))
{
Empty = &obj->q2;
nonEmpty = &obj->q1;
}
while(QueueSize(nonEmpty)>1)
{
QueuePush(Empty, QueueFront(nonEmpty));
QueuePop(nonEmpty);
}
int top = QueueFront(nonEmpty);
QueuePop(nonEmpty);
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)
{
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
obj = NULL;
}
相关OJ题 232. 用栈实现队列 - 力扣(LeetCode)
为了使用栈实现队列,我们可以使用两个栈 s1
和 s2
。在入队操作时,我们将元素压入栈 s1
;在出队操作时,如果栈 s2
为空,我们将栈 s1
中的元素全部弹出并压入栈 s2
,然后从栈 s2
中弹出元素。
以下是使用栈实现队列的代码:
#include
#include
#include
#include
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 初始化与销毁
void STInit(ST* pst);
void STDestory(ST* pst);
// 入栈 出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
// 取栈顶数据
STDataType STTop(ST* pst);
// 判空
bool STEmpty(ST* pst);
// 获取数据的个数
int STSize(ST* pst);
// 初始化与销毁
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STDestory(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = pst->capacity = 0;
}
// 入栈 出栈
void STPush(ST* pst, STDataType x)
{
assert(pst);
// 扩容
if(pst->top == pst->capacity)
{
int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity* sizeof(STDataType));
if(tmp == NULL)
{
perror("realloc fail");
exit(1);
}
pst->a = tmp;
pst->capacity = newcapacity;
}
// 入栈
pst->a[pst->top] = x;
pst->top++;
}
void STPop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
// 取栈顶数据
STDataType STTop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top - 1];
}
// 判空
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
// 获取数据的个数
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
typedef struct
{
ST s1;
ST s2;
} MyQueue;
MyQueue* myQueueCreate()
{
MyQueue* pst = (MyQueue*)malloc(sizeof(MyQueue));
STInit(&pst->s1);
STInit(&pst->s2);
return pst;
}
void myQueuePush(MyQueue* obj, int x)
{
if(!STEmpty(&obj->s1))
{
STPush(&obj->s1, x);
}
else
{
STPush(&obj->s2, x);
}
}
int myQueuePop(MyQueue* obj)
{
ST* Empty = &obj->s1;
ST* nonEmpty = &obj->s2;
if(!STEmpty(&obj->s1))
{
Empty = &obj->s2;
nonEmpty = &obj->s1;
}
while(STSize(nonEmpty) > 1)
{
STPush(Empty, STTop(nonEmpty));
STPop(nonEmpty);
}
int top = STTop(nonEmpty);
STPop(nonEmpty);
while(!STEmpty(Empty))
{
STPush(nonEmpty, STTop(Empty));
STPop(Empty);
}
return top;
}
int myQueuePeek(MyQueue* obj)
{
ST* Empty = &obj->s1;
ST* nonEmpty = &obj->s2;
if(!STEmpty(&obj->s1))
{
Empty = &obj->s2;
nonEmpty = &obj->s1;
}
while(STSize(nonEmpty) > 1)
{
STPush(Empty, STTop(nonEmpty));
STPop(nonEmpty);
}
int top = STTop(nonEmpty);
STPush(Empty, STTop(nonEmpty));
STPop(nonEmpty);
while(!STEmpty(Empty))
{
STPush(nonEmpty, STTop(Empty));
STPop(Empty);
}
return top;
}
bool myQueueEmpty(MyQueue* obj)
{
return (STEmpty(&obj->s1) && (STEmpty(&obj->s2)));
}
void myQueueFree(MyQueue* obj)
{
STDestory(&obj->s1);
STDestory(&obj->s2);
free(obj);
obj = NULL;
}
s1
。s1
移动到栈 s2
一次。通过使用队列实现栈和使用栈实现队列,我们可以更好地理解栈和队列的特性,以及它们之间的转换关系。在实际应用中,我们可以根据具体的需求选择合适的数据结构来实现相应的功能。