StackOrQueueOJ3:用栈实现队列

目录


题目描述

原题:232. 用栈实现队列


思路分析

有了前面的用队列实现栈的基础我们不难想到这题的基本思路,也就是用两个栈来实现队列,(栈的实现具体参考:栈及其接口的实现

c 复制代码
typedef struct {
    Stack PushSt;
    Stack PopSt;
} MyQueue;

PushSt用来插入数据
PopSt用来出数据

入队列那直接对PushSt进行入栈即可;

那也就我们只要进行出队列或去对头元素我们就需要将PushSt栈中的元素依次入栈到PopSt中,我们就可以就这个功能写一个专用的接口:

c 复制代码
void PushStToPopSt(MyQueue* obj)
{
    if (StackEmpty(&obj->PopSt))
    {
        while(!StackEmpty(&obj->PushSt))
        {
            StackPush(&obj->PopSt,StackTop(&obj->PushSt));
            StackPop(&obj->PushSt);
        }
    }
}

这样实现这题就不难了:

开辟队列

如果这里用MyQueue q来创建队列,由于在函数内是个局部变量,所以会创建失败;

c 复制代码
MyQueue* myQueueCreate() {
    MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
    
    if(q == NULL)
    {
        perror("malloc");
        exit(-1);
    }
    StackInit(&q->PushSt);
    StackInit(&q->PopSt);
    return q;
}

入队列

根据上面的分析,很容易写出:

c 复制代码
void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->PushSt,x);
    
}

出队列

同上面的分析:

c 复制代码
int myQueuePop(MyQueue* obj) {
    PushStToPopSt(obj);

    int ret = StackTop(&obj->PopSt);
    StackPop(&obj->PopSt);
    return ret;
}

代码展示

c 复制代码
typedef int STDataType;

// 支持动态增长的栈
typedef struct Stack
{
	STDataType* _a;
	int _top;  //栈顶指针
	int _capacity; //动态容量
}Stack;


//栈的初始化
void StackInit(Stack* pst);

//栈的销毁
void StackDestory(Stack* pst);

//入栈
void StackPush(Stack* pst, STDataType x);

//出栈
void StackPop(Stack* pst);

//获取数据的个数
int StackSize(Stack* pst);    //考虑到内存和统一性问题我们这里也传一级指针

//判空,1是空,0是非空
int StackEmpty(Stack* pst);

//获取栈顶数据
STDataType StackTop(Stack* pst);

//栈的初始化
void StackInit(Stack* pst)
{
	assert(pst);
	//这样会给后面扩容造成麻烦
	/*pst->_a = NULL;
	pst->_top = 0;
	pst->_capacity = 0;*/

	pst->_a = (STDataType*)malloc(sizeof(STDataType) * 4);
	pst->_top = 0;
	pst->_capacity = 4;
}

//栈的销毁
void StackDestory(Stack* pst)
{
	assert(pst);
	free(pst->_a); //释放开辟的空间
	pst->_a = NULL;
	pst->_top = pst->_capacity = 0;
}

//入栈
void StackPush(Stack* pst, STDataType x)
{
	//检查是否需要扩容
	if (pst->_top == pst->_capacity)
	{
		pst->_capacity *= 2;
		STDataType* tmp = (STDataType*)realloc(pst->_a, sizeof(STDataType) * pst->_capacity);
		if (tmp == NULL)
		{
			perror("relloc");
			exit(-1);
		}
		else
		{
			pst->_a = tmp;
		}
	}

	pst->_a[pst->_top] = x;
	pst->_top++;
}

//出栈
void StackPop(Stack* pst)
{
	assert(pst);
	assert(pst->_top > 0);
	//只需要将top一走,可以不用初始化出栈的值
	//pst->_a[pst->_top] = 0;
	pst->_top--;
}

//获取数据的个数
int StackSize(Stack* pst)   //考虑到内存和统一性问题我们这里也传一级指针
{
	assert(pst);
	return pst->_top;
}

//判空,1是空,0是非空
int StackEmpty(Stack* pst)
{
	assert(pst);
	//return pst->_top == 0 ? 1 : 0;
	return !pst->_top;
}

//获取栈顶数据
STDataType StackTop(Stack* pst)
{
	assert(pst);
	assert(pst->_top);

	return pst->_a[pst->_top-1];
}



typedef struct {
    Stack PushSt;
    Stack PopSt;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
    
    if(q == NULL)
    {
        perror("malloc");
        exit(-1);
    }
    StackInit(&q->PushSt);
    StackInit(&q->PopSt);
    return q;
}

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

void PushStToPopSt(MyQueue* obj)
{
    if (StackEmpty(&obj->PopSt))
    {
        while(!StackEmpty(&obj->PushSt))
        {
            StackPush(&obj->PopSt,StackTop(&obj->PushSt));
            StackPop(&obj->PushSt);
        }
    }
}

int myQueuePop(MyQueue* obj) {
    PushStToPopSt(obj);

    int ret = StackTop(&obj->PopSt);
    StackPop(&obj->PopSt);
    return ret;
}

int myQueuePeek(MyQueue* obj) {
    PushStToPopSt(obj);
    return StackTop(&obj->PopSt);
}

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->PushSt) && StackEmpty(&obj->PopSt);
}

void myQueueFree(MyQueue* obj) {
    StackDestory(&obj->PushSt);
    StackDestory(&obj->PopSt);

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

也是通过了leetcode:


相关推荐
rylshe131417 分钟前
在scala中sparkSQL连接mysql并添加新数据
开发语言·mysql·scala
小宋加油啊17 分钟前
Mac QT水平布局和垂直布局
开发语言·qt·macos
czy878747529 分钟前
两种常见的C语言实现64位无符号整数乘以64位无符号整数的实现方法
c语言·算法
MyhEhud37 分钟前
kotlin @JvmStatic注解的作用和使用场景
开发语言·python·kotlin
想睡hhh43 分钟前
c++进阶——哈希表的实现
开发语言·数据结构·c++·散列表·哈希
Clown951 小时前
Go语言爬虫系列教程(一) 爬虫基础入门
开发语言·爬虫·golang
Watermelo6171 小时前
前端如何应对精确数字运算?用BigNumber.js解决JavaScript原生Number类型在处理大数或高精度计算时的局限性
开发语言·前端·javascript·vue.js·前端框架·vue·es6
打鱼又晒网2 小时前
数据类型:List
数据结构·list
java程序员CC2 小时前
记录为什么LIst数组“增删慢“,LinkedList链表“查改快“?
数据结构·链表·list
Aric_Jones3 小时前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua