栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【Leetcode】用队列实现栈(纯C)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Leetcode】用队列实现栈(纯C)

 225. 用队列实现栈 - 力扣(LeetCode) (leetcode-cn.com)

先看题目要求,用两个队列实现栈,我们先把之前写过的队列相关的一些函数拿来:

typedef int QDataType;


typedef struct QNode
{
	QDataType data;
	struct queue* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;




void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	assert(newnode);

	newnode->data = x;
	newnode->next = NULL;

	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail);

	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

bool QueueEmpty(Queue* q)
{
	assert(q);

	return q->head == NULL;
}

size_t QueueSize(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	size_t size = 0;
	while (cur)
	{
		size++;
		cur = cur->next;
	}

	return size;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);

	return pq->tail->data;
}

这里用两个队列实现,所以我们创建一个结构体:

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

结构体里面两个指针,每一个指针对应一个队列,然后我们正式开始写这道题

--------

先从初始化函数开始:
MyStack* myStackCreate() {
	
}

单看函数,它需要返回一致MyStack* 的指针,既然要返回指针,那我们就得用malloc开辟空间,然后开辟好的MyStack结构体其中的Queue结构体,我们可以直接调用其初始化函数,然后即可。

MyStack* myStackCreate() {
    //开辟空间
	MYStack* obj = (MYStack*)malloc(sizeof(MyStack));
    //最好判断一下开辟成功没    
    assert(obj);

    //初始化obj结构体里面的Queue结构体
    QueueInit(&obj->q1);
    QueueInit(&obj->q2);
    
    //返回初始化好的结构体
    return obj;
}
将元素X压入栈顶:

先说说思路:

我们现在有两个队列,两个队列分别有头尾指针,假设现在要将 1 2压入栈,那我们找其中一个不是空的队列压进去:

 这样方便我们之后的一系列操作:

void myStackPush(MyStack* obj, int x) {
    assert(obj);

    //判断obj->q1是否为空,不为空压q1
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    //其他情况压q2
    else
    {
        QueuePush(&obj->q2,x);
    } 
}

     移除并返回栈顶元素:

还是先看思路,我们要移除并且返回栈顶的元素,因为栈是先后后出,所以我们刚刚压进来的 1 2出的时候就应该是 2 1。

按照之前玩单链表的思路,我们就应该是先找到最后一个节点,保存里面的值,然后释放掉最后节点,但是这题要用到第二个队列,所以这样做就有点跑题,这里我们换一种办法。

已知 q1 里面有 1 2,我们要返回 2

我们拿q2来接收q1里面的值,直到q1 里面只剩一个值位置,然后我们保存这个值再将其释放掉,下一次压栈压的就是q2的位置,如果还要移除的话就把q2的值移到q1里面。

 将q1的1拿过来:

 然后返回q1里面的值,再将其置为空:

 假设现在要尾插 3 4 5:

 然后再出来就把1 3 4 移到q1里面:

重复即可,然后我们就来实现代码:

int myStackPop(MyStack* obj) {
    assert(obj);
    Queue* empty = &obj->q1;
    Queue* noempty = &obj->q2;

    if(!QueueEmpty(&obj->q1))
    {
        noempty = &obj->q1;
        empty = &obj->q2;
    }

    while(QueueSize(noempty) > 1)
    {
        QueuePush(empty,QueueFront(noempty));
        QueuePop(noempty);
    }

    int data = QueueFront(noempty);
    QueuePop(noempty);
    return data;
}

 一行一行看:

先判断obj不为空指针,然后假设空的那个队列是q1,非空的是q2,然后判断,如果q1是非空的,那就让非空的指向q1,空的指向q2

如果非空链表里面留下的节点数量大于1,说明我们还要移动

我们在空链表的后面尾插,尾插的是非空链表的元素

比方说刚刚的 1 2

那我们就把1移过去

每次移完记得删掉原本节点,不然程序会死循环

当循环结束,就意味着非空队列里面只有一个元素了,我们获取到这个元素之后再将这个节点也删掉,返回我们获得的元素。

返回栈顶元素:

返回栈顶元素,也就是返回我们最后压进去的元素,正因为我们每次压栈都是在非空队列尾插,所以我们可以直接返回非空节点的最后一个元素即可:

int myStackTop(MyStack* obj) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    return QueueBack(&obj->q2);
}

判断栈是否为空:

我们只需要判断两个队列即可,调用一下我们之前写的判断队列的函数:

ibool myStackEmpty(MyStack* obj) {
    assert(obj);
    return QueueEmpty(&obj->q1)&& QueueEmpty(&obj->q2);
}

销毁栈:

 这个更是简单,我们还是直接调用销毁队列的两个函数,最后释放掉我们的obj即可

void myStackFree(MyStack* obj) {
    assert(obj);
    QueueDestory(&obj->q1);
    QueueDestory(&obj->q2);
    free(obj);
}

这里放上全部代码,有需要可以复制:

typedef int QDataType;


typedef struct QNode
{
	QDataType data;
	struct queue* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

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


void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	assert(newnode);

	newnode->data = x;
	newnode->next = NULL;

	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail);

	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

bool QueueEmpty(Queue* q)
{
	assert(q);

	return q->head == NULL;
}

size_t QueueSize(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	size_t size = 0;
	while (cur)
	{
		size++;
		cur = cur->next;
	}

	return size;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);

	return pq->tail->data;
}



MyStack* myStackCreate() {
	MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    assert(obj);

    QueueInit(&obj->q1);
    QueueInit(&obj->q2);

    return obj;
}

void myStackPush(MyStack* obj, int x) {
    assert(obj);

    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    } 
}

int myStackPop(MyStack* obj) {
    assert(obj);
    Queue* empty = &obj->q1;
    Queue* noempty = &obj->q2;

    if(!QueueEmpty(&obj->q1))
    {
        noempty = &obj->q1;
        empty = &obj->q2;
    }

    while(QueueSize(noempty) > 1)
    {
        QueuePush(empty,QueueFront(noempty));
        QueuePop(noempty);
    }

    int data = QueueFront(noempty);
    QueuePop(noempty);
    return data;
}

int myStackTop(MyStack* obj) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    return QueueBack(&obj->q2);
}

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

void myStackFree(MyStack* obj) {
    assert(obj);
    QueueDestory(&obj->q1);
    QueueDestory(&obj->q2);
    free(obj);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/783993.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号