ledcode【用队列实现栈】

news2024/9/30 19:37:27

目录

题目描述:

解析题目

 代码解析

1.封装一个队列

1.2封装带两个队列的结构体

1.3封装指向队列的结构体

1.4入栈函数实现

1.5出栈函数实现

1.6取栈顶数据

1.7判空函数实现


 

题目描述:

解析题目

这个题我是用c语言写的,所以队列的push,pop,destroy,empty等常规操作我都写好了,后面我会单独出一个章节,写 队列的实现,这章主要想梳理做题步骤。

队列是先进先出,栈呢是先进后出,所以我们要用两个队列配合使用,让后进去的,先出来,我们可以选择其中一个空队列,讲所有数据一次push入队,然后利用另外一个队列,将这个非空的队列的队头数据,依次如到另一个空的队列,折旧就把最后一个进队的数据保留下来了 这次在pop一下就完成了 题目的要求 最后进的 第一个出来,而且该队列为空了;同时,再接下来,入过有数据,一定要让它入非空队列,然后再执行上述操作,就可以又把最后一个数据单独留在一个队里中,再pop就完成栈的后进先出的操作了。详解图如下所示:

 

 代码解析

 

1.封装一个队列

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


typedef int QDataType;
//定义节点
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;

}QNode;
//定义指向头和尾的指针
typedef struct	Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;


void QueueInit(Queue* pq)
{

	pq->head = pq->tail = NULL;
	pq->size = 0;

}
//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode *cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;	
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;

}
QNode* BuyQNode(QDataType x)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc:fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
//进队
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = BuyQNode(x);
	if (pq->head == NULL)
	{
		pq->head = pq->tail= newnode;

	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}
//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;

}
//出队
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* del = pq->head;//结构体成员head 是QNode 类型指针
		pq->head = pq->head->next;
		free(del);
	}
	pq->size--;

}
//队头
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;

}

//个数
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}


1.2封装带两个队列的结构体

因为是用ledecode写的代码,所以写的代码都按照他给定的封装结构编写,具体代码如下:

//两个队列封装在一个结构体中 重定义为 Mystack
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

1.3封装指向队列的结构体

题目中已经给了接口函数,我们只能在接口函数内部,完成要求,具体代码如下

MyStack* myStackCreate() {
    MyStack *obj = ( MyStack *)malloc(sizeof(MyStack));//定义一个结构体指针变量,
    QueueInit(&obj->q1);//初始化
    QueueInit(&obj->q2);
    return obj;

}

因为题目给是返回的是mystack*结构指针变量,所以 函数内部,我们定义一个指针变量,用来接收在堆上申请的同类型的空间地址,这样虽然出了子程序后,变量obj会被释放,但是地址我们已经返回,并且堆上的空间已经被返回,我们可以通过地址访问这块空间。

1.4入栈函数实现

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

}

这个就很简单,如果队列1为空就把数据入队,反之入队列2。

1.5出栈函数实现

int myStackPop(MyStack* obj) {
//写一个判断队列1和队列2谁为空的代码
    Queue *emptyQueue = &obj->q1;  //定义一个指针变量 emptyQueue,就要取出obj->q1的地址来匹配
     Queue *noemptyQueue = &obj->q2;
     if(!QueueEmpty(&obj->q1))
     {
        noemptyQueue = &obj->q1;
        emptyQueue = &obj->q2;

     }
//将不为空的队列除了最后一个数据其他数据都入到另一个空队中
   while(QueueSize(noemptyQueue)>1)
   {
       QueuePush(emptyQueue,QueueFront(noemptyQueue));//取队头数据,依次如另一个队中
       QueuePop(noemptyQueue);//出一个数据,要pop一下
   }
     int top = QueueFront(noemptyQueue);//因为要返回 栈的数据,所以用一个整形变量接收
      QueuePop(noemptyQueue);

      return top;
}

 用两个结构体指针变量接收队列1 和2 判断出他们中为不空的队列,然后依次入空的队列,保留最后一个数据,取出返回,就完成啦,每个代码的解析我都写出来了。

1.6取栈顶数据

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

 就是将不为空的队列的队尾数据返回就行。

1.7判空函数实现

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

}

 表达式 的意思是 两个队列同时为空 才为真 返回true 否则返回false

1.8销毁函数实现

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

}

我们需要先将,队列1和队列2 销毁,再将0bj这个指针变量置空,如果直接置空obj,那么结构体里面的队列还是有指向,不会销毁,这样会造成内存泄漏,如下图所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/374901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

魔兽世界WoW注册网站搭建——-Liunx

问题背景哎 搭建了一个魔兽3.35&#xff08;纯洁版&#xff09;每当同学朋友要玩的时候我都直接worldserver上面打一个命令随之出现朋友的朋友也要玩想了想还是要有一个网站原本以为吧单机版里面网页的IP数据库改下可以了结果PHP报错了Unknown column sha_pass_hash in field l…

学校AI视频行为分析监测系统 opencv

学校AI视频行为分析监测系统通过pythonopencv网络模型AI视频分析技术&#xff0c;学校AI视频行为分析监测算法对学校区域人员打架行为识别、跌倒行为识别、翻墙识别、人员聚众识别、攀高识别、抽烟行为等进行智能识别预警。OpenCV的全称是Open Source Computer Vision Library&…

C#专栏目录(长期更新)

文章目录C# 基础C#进阶C#应用WPF基础WPF 3D小游戏C# 基础 1996年&#xff0c;微软用年薪三百万美刀的价格从Borland挖来了大神海尔斯伯格&#xff0c;开始了J开发&#xff0c;用以对抗Java。但SUN公司认为此举违反了Java开发平台的中立性&#xff0c;对微软提出诉讼。C#正是在…

RBAC 权限模型介绍

RBAC 权限&#xff1a; 一、关系&#xff1a; 这基于角色的访问控制的结构就叫RBAC结构。 二、RBAC 重要对象&#xff1a; 用户&#xff08;Employee&#xff09;&#xff1a;角色施加的主体&#xff1b;用户通过拥有某个或多个角色以得到对应的权限。角色&#xff08;Role&…

SQL零基础入门学习(十三)

上一篇&#xff08;SQL零基础入门学习&#xff08;十二&#xff09;&#xff09; SQL 视图&#xff08;Views&#xff09; 视图是可视化的表。 SQL CREATE VIEW 语句 在 SQL 中&#xff0c;视图是基于 SQL 语句的结果集的可视化的表。 视图包含行和列&#xff0c;就像一个…

jsp+servlet+javabean新闻发布系统

技术&#xff1a;Java、JSP等摘要&#xff1a;近年来,Internet技术得到迅速的发展,已经成为计算机产业的一个技术热点。促成Internet高速发展的因素之一就是Web技术。Web技术的发展使得那些具有交互动态页面、有条理的数据库查询、丰富信息内容的页面成为最吸引人的网页。浏览W…

MVCC 当前读 快照读 RC read view RR下事务更新不会丢失

MVCC(multi-version-concurrent-control) MVCC是行锁的一个变种&#xff0c;但MVCC在很多情况下它避免了加锁。不是buffer块&#xff0c;而是buffer中的记录行。 MVCC (Multi-Version Concurrency Control) (注&#xff1a;与MVCC相对的&#xff0c;是基于锁的并发控制&#x…

SVIP优先办理服务-课后程序(JAVA基础案例教程-黑马程序员编著-第八章-课后作业)

【案例8-2】 Svip优先办理服务 【案例介绍】 1.任务描述 在日常工作生活中&#xff0c;无论哪个行业都会设置一些Svip用户&#xff0c;Svip用户具有超级优先权&#xff0c;在办理业务时&#xff0c;Svip用户具有最大的优先级。 本案例要求编写一个模拟Svip优先办理业务的程…

350-401-拖图题1

拖图题 QoS&#xff1b;policing&#xff1a;dropped,no delay;shaping:buffers,delay&#xff1b;policing有TCP和no。shaping有buffer缓冲器和delay延迟&#xff1b;警察安全不丢失&#xff0c;定型过多延迟又延迟 traffic policing&#xff1a;流量监管 causes TCP retran…

JUnit介绍与使用

自动化是通过selenium脚本来实现的&#xff0c;而JUnit是Java单元测试工具&#xff0c;只不过我们在实现自动化的时候要借用一些JUnit库里提供的一些方法。优化我们的自动化使用版本&#xff1a;JUnit5&#xff08;支持最低Java版本为8&#xff09;依赖导入到pom.xml&#xff1…

浅谈权限获取方法之文件上传

概述 文件上传漏洞是发生在有上传功能的应用中&#xff0c;如果应用程序对用户的上传文件没有控制或者存在缺陷&#xff0c;攻击者可以利用应用上传功能存在的缺陷&#xff0c;上传木马、病毒等有危害的文件到服务器上面&#xff0c;控制服务器。 漏洞成因及危害 文件上传漏…

如何进行域名购买,获取免费ssl证书,使用springboot绑定ssl证书

前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注一下&#xff01;也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff0c;才能走的更远&#xff01;让我们在成长的道路上互相学习&#…

Linux修改文件属性和权限

本次我们还是使用CentOS7来进行实验查看文件属性首先我们可以使用ll命令来查看某一文件的属性现在可以拆分一下-rw-r--r--1rootroot3042月27 22:58kaka文件类型文件所有者权限用户组权限其他人权限硬链接次数属主属组文件大小最后修改时间文件名1.文件类型-普通文件&#xff0c…

python同步线程

线程同步可以定义为一种方法&#xff0c;借助这种方法&#xff0c;可以确信两个或更多的并发线程不会同时访问被称为临界区的程序段。 另一方面&#xff0c;正如我们所知道的那样&#xff0c;临界区是共享资源被访问的程序的一部分。 因此&#xff0c;同步是通过同时访问资源来…

MIT 6.S081学习笔记

计划花25天时间学完6.S081课程&#xff0c;从2月20日-3月20日。课程主页Link   xv6 book   GDB User Manual Lecture 1: Introduction and Examples课程主题&#xff1a;设计和实现操作系统   OS的三大功能&#xff1a;多路复用、隔离和交互。 Lab: Xv6 and Unix utiliti…

“ChatGPT之父”Sam Altman:我是如何成功的?

背靠微软&#xff0c;OpenAI能拳打谷歌&#xff0c;脚踢Meta&#xff0c;它背后的男人&#xff0c;必然不简单。 让我们来看一看&#xff0c;Sam Altman是如何一步步成长为今天这个搅动全世界的男人。 山姆奥特曼&#xff08;Sam Altman&#xff09; 成长和创业经历 在YC创始…

数据结构(Java版)绪论

一、数据结构绪论 1、概论 &#x1f34e;数据结构研究计算机的操作对象以及他们之间的关系和操作。 2、算法的定义、特征、设计要求 算法&#xff1a;是对特定问题求解步骤的一种描述&#xff0c;它是指令的有限序列&#xff0c;是一系列输入转化为输出的计算步骤。 算法的特…

篮球杯 双指针专题

总的来说&#xff0c;双指针分为while(1)类型和尺取法类型可以解决各种问题&#xff08;如子序列问题&#xff09;活动 - AcWing思路&#xff1a;while(1)型的双指针基本形式为&#xff1a;while(1){if(l>n||r>n) break;while(条件&&l<n) l;rl;while(条件&…

使用Platform Designer创建Nios II 最小系统

Nios II简介 ​ Nios II 软核处理器十多年前就有了&#xff0c;它和xilinx的MicroBlaze类似&#xff0c;性能相比硬核处理器要差得多&#xff0c;工程应用也不是很多&#xff0c;那还有必须学习一下吗&#xff1f;我个人认为了解一下Nios II开发流程&#xff0c;对intel FPGA开…

9.网站数据统计

1.Redis 高级数据类型&#xff08;1&#xff09;HyperLogLog统计20万个重复数据的独立总数// 统计20万个重复数据的独立总数. Test public void testHyperLogLog() {String redisKey "test:hll:01";for (int i 1; i < 100000; i) {redisTemplate.opsForHyperLog…