leetcode 栈和队列的互相实现

Posted Allen9012

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 栈和队列的互相实现相关的知识,希望对你有一定的参考价值。

1. 用队列实现栈

本题目来源于leetcode225. 用队列实现栈

1.1 题目描述

示例

注意和提示

1.1.1 接口函数

typedef struct 

 MyStack;


MyStack* myStackCreate() 



void myStackPush(MyStack* obj, int x) 



int myStackPop(MyStack* obj) 



int myStackTop(MyStack* obj) 



bool myStackEmpty(MyStack* obj) 



void myStackFree(MyStack* 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);
*/

1.2 大致框架

注意要实现功能,利用先进先出的队列达成后进先出的

这里还是同样的,用c语言的话肯定是要先实现一下队列

1.2.1 想法和思路

这两个队列,保证在插入数据的时候,往不为空的那个队列插入,保持另一个队列是空的,出队列的时候,使前size-1个导入空队列,删除最后一个

1.2.2 具体步骤

先实现一个栈

#include <stdbool.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef int QDataType;

typedef struct QueueNode

	struct QueueNode* next;
	QDataType data;

QueueNode;

typedef struct Queue

	QueueNode* head;
	QueueNode* tail;
Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)

	assert(pq);
	pq->head = pq->tail = NULL;

void QueueDestroy(Queue* pq)

	assert(pq);
	QueueNode* cur = pq->head;
	while (cur)
	
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	
	pq->head = pq->tail = 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->head == NULL)//如果一个节点都没有
	
		pq->head = pq->tail = newnode;
	
	else//正经插入数据
	
		pq->tail->next = newnode;
		pq->tail = newnode;
	

void QueuePop(Queue* pq)

	//先进的先出,就是头删
	assert(pq);//空指针
	assert(!QueueEmpty(pq));//空
	if (pq->head->next == NULL)//一个节点的时候要特殊考虑
	
		free(pq->head);
		pq->head = pq->tail = NULL;
	
	else
	
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	

QDataType QueueFront(Queue* pq)

	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;

QDataType QueueBack(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);
	int size = 0;
	QueueNode* cur = pq->head;
	while (cur)
	
		++size;
		cur = cur->next;
	
	return size;

然后处理实现栈过程

MyStack

typedef struct 
    Queue q1;
    Queue q2;
 MyStack;

myStackCreate

MyStack* myStackCreate() 
    MyStack*pst=(MyStack*)malloc(sizeof(MyStack));
    QueueInit1(&pst->q1); 
    QueueInit2(&pst->q2);
    return pst;

myStackPush

往不为空的队列里面入数据

void myStackPush(MyStack* obj, int x) 
 if(QueueEmpty(&obj->q1))//谁空放哪里
 
     QueuePush(&obj->q1,x);
 
 else
 
     QueuePush(&obj->q2,x);
 

myStackPop

后入的先出,所以,想法是把数据按照队列的方式先出,出到另外一个队列里面

如图,假如数据进入的顺序是1,2,3,4

先把123放到另外一个队列之中,然后把4用队列的删除pop掉就可以了

int myStackPop(MyStack* obj) 
    Queue*pEmpty=&obj->q1;
    Queue*pNonEmpty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    
        pNonEmpty=&obj->q1;
        pEmpty=&obj->q2;
    
    while(QueueSize(pNonEmpty)>1)
    //取一个插一个删一个,取一个插一个删一个
        QueuePush(pEmpty,QueueFront(pNonEmpty));
        QueuePop(pNonEmpty);
    
    //最后一个干掉
    int front=QueueFront(pNonEmpty);
    QueuePop(pNonEmpty);
    return front;
 

myStackTop

int myStackTop(MyStack* obj) 
if(QueueEmpty(&obj->q1))
 //队尾的数据就是栈顶
     return QueueBack(&obj->q1);
 
 else
 
    return QueueBack(&obj->q2);
 

myStackEmpty

都是空的才说明是空的

bool myStackEmpty(MyStack* obj) 
 return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);

myStackFree

void myStackFree(MyStack* obj) 
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
 free(obj);

1.2.3 测试时发生的错误

解决第一个错误

显然是一个测试用例都没有通过

int myStackTop(MyStack* obj) 
if(QueueEmpty(&obj->q1))//检查了一遍发现缺了感叹号,也就是Top,那如果没有!就返回了空队列肯定不对
 //队尾的数据就是栈顶
     return QueueBack(&obj->q1);
 
 else
 
    return QueueBack(&obj->q2);
 

但是显然这不会使得超出时间限制,所以继续检查

解决第二个错误

void myStackPush(MyStack* obj, int x) 
 if(QueueEmpty(&obj->q1))//谁空放哪里
 
     QueuePush(&obj->q1,x);
 
 else
 
     QueuePush(&obj->q2,x);
 

很尴尬😅这里也忘了,一样的问题

但是还没完

解决第三个错误

既然都不是那一定是队列写错了

然后一找发现bug后直接吐血😭

为什么会在while(cur)后面加一个

怪不得程序停不下来

int QueueSize(Queue* pq)

	assert(pq);
	int size = 0;
	QueueNode* cur = pq->head;
	while (cur)
		++size;
		cur = cur->next;
	
	return size;

总算解决了心,队列要好好写啊

1.3 整体实现

#include <stdbool.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef int QDataType;

typedef struct QueueNode

	struct QueueNode* next;
	QDataType data;

QueueNode;

typedef struct Queue

	QueueNode* head;
	QueueNode* tail;
Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)

	assert(pq);
	pq->head = pq->tail = NULL;

void QueueDestroy(Queue* pq)

	assert(pq);

	QueueNode* cur = pq->head;
	while (cur)
	
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	
	pq->head = pq->tail = 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->head == NULL)//如果一个节点都没有
	
		pq->head = pq->tail = newnode;
	
	else//正经插入数据
	
		pq->tail->next = newnode;
		pq->tail = newnode;
	

void QueuePop(Queue* pq)

	//先进的先出,就是头删
	assert(pq);//空指针
	assert(!QueueEmpty(pq));//空
	if (pq->head->next == NULL)//一个节点的时候要特殊考虑
	
		free(pq->head);
		pq->head  = pq->tail = NULL;
	
	else
	
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	

QDataType QueueFront(Queue* pq)

	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;

QDataType QueueBack(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);
	int size = 0;
	QueueNode* cur = pq->head;
	while (cur)
	
		++size;
		cur = cur->next;
	
	return size;


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*pEmpty=&obj->q1;
    Queue*pNonEmpty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    
        pNonEmpty=&obj->q1;
        pEmpty=&obj->q2;
    
    while(QueueSize(pNonEmpty)>1)
    //取一个插一个删一个,取一个插一个删一个
        QueuePush(pEmpty,QueueFront(pNonEmpty));
        QueuePop(pNonEmpty);
    
    //最后一个干掉
    int front=QueueFront(pNonEmpty);
    QueuePop(pNonEmpty);
    return front;


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

2. 用栈实现队列

本题目来源于leetcode 232. 用栈实现队列

2.1 题目描述

栈和队列数据结构的相互实现[LeetCode]

Leetcode题解——数据结构之栈和队列

Leetcode Practice --- 栈和队列

leetcode刷题记录——栈和队列

数据结构栈和队列OJ练习(栈和队列相互实现+循环队列实现)

栈和队列OJ题合集(包含循环队列的两种实现)