leetcode经典例题之使用栈实现队列

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

1、题目展示

在这里插入图片描述


  前面我们了解过如何实现栈相关的代码,如果有遗忘或不熟悉可以回看:

     栈(使用顺序表构建)


  下面我们直接进入正文。



2、题目分析


  本题与博主前一篇博客中的使用队列实现栈有大相径庭的部分,但又有一些出入,我们知道栈与队列的区别是前者为后进先出,后者为先进先出,故当我们使用栈来实现队列相关的内容时,需要加以分析。
  我们同样的使用两个栈来进行队列功能的实现,假设一个场景,我们需要先将1,2,3,4四个数据输入至队列中,及s1或s2中(二者皆可)。

在这里插入图片描述
  当我们需要从由栈组成的队列中删除或哪取数据时,在栈先进先出的前提下,我们可以直接将s1中的4,3,2通过栈的输出导入至s2中。
在这里插入图片描述
  此时我们的s1中只剩下了数据1,这时候便可以直接进行取数据或删除数据的操作。
  此时我们假设将数据1删除后有插入了数据5和6,为了方便起见我们不再选择有数据的那一个栈来进行插入操作,反而使用没有数据的那一个,这样的情况下,如果我们需要继续输出或删除数据,我们便可以直接通过STTop对最先插入栈中的数据进行操作。


  既然这样,我们为了方便理解,不如将s1记作pushst,s2记作popst。便有了下图的结果。

在这里插入图片描述

  而判断队列是否为空的逻辑思路显而易见,直接判断两个栈是否都为空即可。




3、完整代码演示


  我们在完成这一道题目时,因为是oj题目,所以在需要完成的功能函数前需要自行书写栈的相关内容代码,故不在此展示,有需要者可在标题1中自行寻找link链接。
typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST,*pST;


//初始化栈
void STInit(pST pst)
{
	assert(pst);
	pst->a = NULL;
	pst->top = 0;
	pst->capacity = 0;
}

//销毁栈
void STDestroy(pST pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}

//入栈
void STPush(pST pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = realloc(pst->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("STPush:relloc");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}

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

//出栈
void STPop(pST pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}

//取栈顶数据
STDataType STTop(pST pst)
{
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top - 1];
}

//判断空
bool STEmpty(pST pst)
{
	assert(pst);
	return pst->top == 0;
}

//数据个数
int STSize(pST pst)
{
	assert(pst);
	return pst->top;
}


typedef struct 
{
    ST pushst;
    ST popst;
} MyQueue;


MyQueue* myQueueCreate() 
{
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    STInit(&(obj->pushst));
    STInit(&(obj->popst));

    return obj;    
}

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

int myQueuePop(MyQueue* obj) 
{
    int front = myQueuePeek(obj);
    STPop(&(obj->popst));
    return front;
}

int myQueuePeek(MyQueue* obj) 
{
    if(STEmpty(&(obj->popst)))
    {
        while(!STEmpty(&(obj->pushst)))
        {
            STPush(&(obj->popst),STTop(&(obj->pushst)));
            STPop(&(obj->pushst));
        }
    }
    return STTop(&(obj->popst));
}

bool myQueueEmpty(MyQueue* obj) 
{
    return STEmpty(&(obj->pushst)) && STEmpty(&(obj->popst));
}

void myQueueFree(MyQueue* obj) 
{
    STDestroy(&(obj->pushst));
    STDestroy(&(obj->popst));
    free(obj);
}




4、结语


  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。
;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值