首页 > 其他分享 >队列实现栈

队列实现栈

时间:2023-04-12 13:13:06浏览次数:42  
标签:head pq obj QueNode 队列 Queue 实现

用两个队列实现一个栈

题目链接

题目描述

 

解题思路

首先梳理下队列和栈的概念, 队列是所有数据先入先出, 而栈是后入先出

第二步, 用两个队列结构模拟出一个栈结构

第三步,思考如何用模拟出来的栈,完成入栈, 出栈, 取栈顶数据和判空操作,这里说一下我的思路

入栈: 入不为空的队列,  如果两个队列都为空则入队列2

出栈: 将不为空队列中的数据导入到空的队列中, 让不为空队列只剩一个数据, 最后将这个数据出队, 这样就模拟了出栈操作

取栈顶数据: 取不为空的队尾数据, 就是取栈顶数据

判断栈是否为空: 如果两个队列都没有数据,就表示栈为空

下面代码实现

typedef int QueDataType;
typedef struct QueNode
{
	QueDataType data;
	struct QueNode* next;
}QueNode;

typedef struct Queue
{
	QueNode* head;
	QueNode* tail;
	int size;
}Queue;

// 初始化队列
void QueInit(Queue* pq);
// 销毁队列
void QueDestroy(Queue* pq);
// 入队
void QuePush(Queue* pq, QueDataType x);
// 出队
void QuePop(Queue* pq);
// 计算队列中数据个数
int QueSize(Queue* pq);
// 判空
bool isQueEmpty(Queue* pq);
// 取队头数据
QueDataType QueFront(Queue* pq);
// 取队尾数据
QueDataType QueBack(Queue* pq);
// 初始化
void QueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
// 销毁
void QueDestroy(Queue* pq)
{
	assert(pq);
	QueNode* cur = pq->head;
	while (cur)
	{
		QueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
// 入队
void QuePush(Queue* pq, QueDataType x)
{
	assert(pq);
	QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
	if (NULL == newnode)
	{
		perror("QuePush::malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

	if (NULL == pq->head)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
// 出队
void QuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	// 处理单个节点的特殊情况
	if (NULL == pq->head->next)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}
// 计算队列中数据个数
int QueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
// 判空
bool isQueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}
// 取队头数据
QueDataType QueFront(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->head->data;
}
// 取队尾数据
QueDataType QueBack(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->tail->data;
}

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


MyStack* myStackCreate() {
    MyStack* st = malloc(sizeof(MyStack));
    // 初始化
    QueInit(&st->q1);
    QueInit(&st->q2);
    return st;
}

void myStackPush(MyStack* obj, int x) {
    if (isQueEmpty(&obj->q1))
    {
        QuePush(&obj->q2, x);
    }
    else 
    {
        QuePush(&obj->q1, x);
    }
}

int myStackPop(MyStack* obj) {
    Queue* EmptyQue = &obj->q2;
    Queue* NoneEmptyQue = &obj->q1;
    if (isQueEmpty(&obj->q1))
    {
        EmptyQue = &obj->q1;
        NoneEmptyQue = &obj->q2;
    }
    while (QueSize(NoneEmptyQue) > 1)
    {
        QuePush(EmptyQue, QueFront(NoneEmptyQue));
        QuePop(NoneEmptyQue);
    }
    int ret = QueFront(NoneEmptyQue);
    QuePop(NoneEmptyQue);
    return ret;
}

int myStackTop(MyStack* obj) {
    if (isQueEmpty(&obj->q1))
    {
        return QueBack(&obj->q2);
    }
    else 
    {
        return QueBack(&obj->q1);
    }
}

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

void myStackFree(MyStack* obj) {
    QueDestroy(&obj->q1);
    QueDestroy(&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);
*/

 

标签:head,pq,obj,QueNode,队列,Queue,实现
From: https://www.cnblogs.com/xumu11291/p/17309455.html

相关文章

  • UVa 757 / POJ 1042 / East Central North America 1999 Gone Fishing (枚举&贪心&想
    757-GoneFishingTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=698http://poj.org/problem?id=1042Johnisgoingonafishingtrip.Hehas h hoursavailable( ),andther......
  • 开源在线客服系统-客服系统历史消息记录功能-点击加载历史聊天记录-分页展示历史消息
    之前开发的开源在线客服系统gofly,访客端一直没有展示历史聊天记录,最近抽时间给加上了实现的效果就是,访客刚进聊天界面,如果存在历史记录,按5条分页,默认查询加载5条聊天记录。如果历史记录超过5条,顶部出现“点击加载更多”按钮,点击按钮就分页查询历史记录,堆入消息记录数组里。 ......
  • 高空安全带算法实现
    1.项目背景由于项目中用到安全带识别算法,所以进行了比较粗略的安全带识别算法的实现,经过我们的资料查阅发现安全帽的识别算法比较普遍,但是安全带的算法比较少,但也不能说没有,几篇罢了,现将实现过程记录如下;需求:每次传入算法一张图片(或者三维数组),经过算法处理后传出一张图片(或者......
  • 第十二篇 手写原理代码 - 实现一个前端并发控制请求函数
    实现并发控制请求函数/***并发控制请求函数*@param{Array}urls请求的URL数组*@param{Number}max最大并发数*@param{Function}callback请求成功回调函数*/asyncfunctionconcurrentRequest(urls,max,callback){constlen=urls.length;//用......
  • 第十三篇 手写原理代码 - 实现 Promise
    当使用JavaScript进行异步编程时,我们往往需要面对回调地狱(callbackhell)、代码可读性低、错误处理困难等问题。为了解决这些问题,ECMAScript6(ES6)中引入了Promise。Promise是一种用于处理异步操作的对象,它是一个容器,保存着未来才会结束的事件(通常是一个异步操作),并提供了一组......
  • 第十一篇 手写原理代码 - 实现事件订阅中类
    javaScript中的订阅发布模式(也称为观察者模式)是一种设计模式,用于在对象之间的事件通信中。该模式由两部分构成:发布者和订阅者。发布者持有所有订阅者的引用,在某个事件发生时通知所有的订阅者,从而触发它们的相应行为。这种模式可以用于解耦发布者和订阅者之间的依赖关系,从而实......
  • 五、基于PVC+StatefulSet实现的MySQL主从架构
    案例(部署mysql)本节使用StatefulSet控制器部署一个MySQL集群,然后进行宕机测试,观察集群是否可以正常恢复使用并且不丢失数据。实现的集群有如下特征:是一个主从复制的MySQL集群1个主节点,多个从节点从节点能够水平扩展所有的写操作,只能在主节点上执行......
  • 手机号码归属地 API 实现个性化推荐的思路分析
    前言随着移动互联网和智能手机的普及,越来越多的人使用手机上网和购物,移动营销已成为企业获取用户和提升品牌知名度的重要手段。手机号码归属地API作为移动营销的关键工具,具有广阔的应用前景。本文将探讨如何利用手机号码归属地API进行个性化推荐和精准广告投放,希望对大家有......
  • nginx+tomcat双端口实现负载均衡
    nginx基础配置---点击tomcat基础配置---点击上述配置完成之后进行对tomcat配置不同端口tomcat设置端口#移动tomcat设置两个主目录[root@lyxlocal]#mvapache-tomcat-8.5.79tomcat-home[root@lyxlocal]#cp-Rtomcat-hometomcat-8080[root@lyxlocal]#cp-Rtomcat-home......
  • 人工智能技术助力医疗行业实现智能化管理和服务优化
    ​ 人工智能技术已经逐渐渗透到各个领域,医疗行业也不例外。人工智能技术的应用,不仅可以提高医疗服务的效率和质量,还可以为医疗行业带来更多的创新和发展。一、人工智能技术在医疗诊断中的应用人工智能技术可以通过对大量的医疗数据进行分析和处理,帮助医生更准确地进行诊断和治......