Leetcode:用队列实现栈,用栈实现队列

2024-01-20 08:14:15 浏览数 (2)

题目描述

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsizeis empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

思路:

首先了解到队列的特点是先进先出,栈的特点是先进后出,然后我们可以创建两个队列来模拟栈。入栈时,直接插入非空队列的队尾(第一次入栈时,任意插入一个队列),出栈时,先将非空队列的元素弹出到另一个队列,留下最后一个元素,再弹出,即弹出队尾元素,判空时,直接判断两个栈是否都为空。

代码语言:javascript复制
//下面的栈都是用C语言写的,为使用STL
// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);


// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);
	q->head = q->tail = NULL;
	q->size = 0;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	newnode->data = data;
	newnode->next = NULL;
	if (q->tail == NULL)
	{
		q->head = q->tail = newnode;
	}
	else
	{
		q->tail->next = newnode;
		q->tail = q->tail->next;
	}
	q->size  ;
}
// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->head);
	QNode* del = q->head;
	q->head = q->head->next;
	free(del);
	del = NULL;
	if (q->head == NULL)
		q->tail = NULL;
	q->size--;

}
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->head);
	return q->head->data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->tail);
	return q->tail->data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->head == NULL;
}
// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* cur = q->head;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}


typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* q=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&q->q1);
    QueueInit(&q->q2);
    return q;
}

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;
    }
    //弹出不为空的队列的队尾元素,将其他元素push到另一个队列
    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) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

/**
 * 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);
*/

用栈实现队列

题目描述

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

思路:

首先创建两个栈,一个栈用来入队列,一个栈用来出队列,出队列时,如果出队列的栈为空,则将入队列的栈中的元素弹出到出队列的栈再出队列,否则,直接出栈。

代码语言:javascript复制
//栈为用 C语言所写
//栈只能先进后出
//每个元素最后进出的相对顺序不唯一,可以边进边出

typedef int STDataType;

typedef struct Stack
{
	int* a;  //存储栈内元素的数组
	int top;		// 标识栈顶位置的,代表栈顶元素的下一个位置(也可以代表是栈顶元素,但栈为空时top==-1)
	int capacity;
}ST;

void STInit(ST* pst);
void STDestroy(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->capacity = 0;

	// 表示top指向栈顶元素的下一个位置
	pst->top = 0;

	// 表示top指向栈顶元素
	//pst->top = -1;
}

void STDestroy(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, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		pst->a = tmp;
		pst->capacity = newcapacity;
	}

	pst->a[pst->top] = x;
	pst->top  ;
}

void STPop(ST* pst)
{
	assert(pst);
	// 不为空
	//assert(pst->top > 0);
	if(pst->top==0)
	return;
	pst->top--;
}

int STTop(ST* pst)
{
	assert(pst);
	// 不为空
	//assert(pst->top > 0);
	if(pst->top==0)
	return NULL;

	return pst->a[pst->top - 1];

}

bool STEmpty(ST* pst)
{
	assert(pst);

	/*if (pst->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/

	return pst->top == 0;
}

int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

typedef struct {
    ST s1;//入队
    ST s2;//出队
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* q=(MyQueue*)malloc(sizeof(MyQueue));
    STInit(&q->s1);
    STInit(&q->s2);
    return q;
}

void myQueuePush(MyQueue* obj, int x) {
    STPush(&obj->s1,x);
}

int myQueuePop(MyQueue* obj) {
    if(STEmpty(&obj->s2))
    {
        while(STSize(&obj->s1)>0)
        {
            STPush(&obj->s2,STTop(&obj->s1));
            STPop(&obj->s1);
        }
    }
    int front=STTop(&obj->s2);
		STPop(&obj->s2);
    return front;
}

int myQueuePeek(MyQueue* obj) {
    if(STEmpty(&obj->s2))
    {
        while(STSize(&obj->s1)>0)
        {
            STPush(&obj->s2,STTop(&obj->s1));
            STPop(&obj->s1);
        }
    }
    return STTop(&obj->s2);
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->s1)&&STEmpty(&obj->s2);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->s1);
    STDestroy(&obj->s2);
    free(obj);
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

0 人点赞