【数据结构】栈和队列 (栈 栈的概念结构 栈的实现 队列 队列的概念及结构 队列的实现 栈和队列面试题)

news2024/11/16 22:51:49

文章目录

  • 前言
  • 一、栈
    • 1.1 栈的概念结构
    • 1.2栈的实现
  • 二、队列
    • 2.1队列的概念及结构
    • 2.2队列的实现
  • 三、栈和队列面试题
  • 总结


前言

一、栈

1.1 栈的概念结构

栈也是一种线性表,数据在逻辑上挨着存储。只允许在固定的一端进行插入和删除元素。进行插入和删除操作的一端叫栈顶,另一端叫栈底。符合LIFO 先进后出。
在这里插入图片描述

压栈:插入操作。
出栈:删除操作。

1.2栈的实现

栈的实现用数组实现更好,因为完美符合数组的尾插尾删。
数组的缓存利用率高一点。
在这里插入图片描述
小练习:
在这里插入图片描述

支持动态增长的栈:

typedef int STDataType;
typedef struct Stack
{
 STDataType* _a;
 int _top; // 栈顶
 int _capacity; // 容量
}Stack;

初始化栈:

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

入栈:进栈(栈的插入操作),若栈未满,则将x加入使之成为新栈顶。

void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

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

出栈:出栈(栈的删除操作),若栈非空,则弹出栈顶元素,并用x返回。

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	--ps->top;
}

获取栈顶元素:

STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}

获取栈中有效元素个数:

int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

销毁栈:栈销毁,并释放占用的存储空间

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

检测栈是否为空,如果为空返回非零结果,如果不为空返回0:

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps);
bool StackEmpty(ST* ps);
int StackSize(ST* ps);
Stack.c
#include "Stack.h"

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

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

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	--ps->top;
}

STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

二、队列

2.1队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为队头。

2.2队列的实现

队列用链表的结构实现更优

在这里插入图片描述

链式结构:表示队列

typedef struct QListNode
{ 
 struct QListNode* _pNext; 
 QDataType _data; 
}QNode;

队列的结构:

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

初始化队列:

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

队尾入队列:

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

	}

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

	pq->size++;
}

队头出队列:

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;
		pq->head = pq->head->next;

		free(del);
		del = NULL;

	}
	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;
}

检测队列是否为空,如果为空返回非零结果,如果非空返回0:

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

销毁队列:

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

	}
	pq->head = pq->tail = NULL;
}
Queue.h
#pragma once
#include <stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

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

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
Queue.c
#include"Queue.h"

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

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

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

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

	}

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

	pq->size++;
}

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;
		pq->head = pq->head->next;

		free(del);
		del = NULL;

	}
	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;
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

三、栈和队列面试题

题目链接:
1.https://leetcode.cn/problems/valid-parentheses/
在这里插入图片描述

在这里插入图片描述

题目链接:
2.https://leetcode.cn/problems/implement-stack-using-queues/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结

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

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

相关文章

记录 UE5 完全重新构建 UE C++项目

不知道搞了什么&#xff0c;C项目的实时代码编译罢工了&#xff0c;搞了半天都修不好&#xff0c;只能又重建了 UE5 版本为 v5.1.1 删除以下文件夹 /Binaries /Intermediate /SavedBinaries 文件夹是编译后的模块 Intermediate 文件夹里是中间层的C代码&#xff0c;完全由ue…

腾讯乐固加固+app签名+多渠道打包

一、腾讯乐固-基础版免费加固-上传未加固的app-下载加固包&#xff08;加固成功会清除原apk的签名信息和多渠道信息&#xff09;https://console.cloud.tencent.com/ms/reinforce/list/basic二、使用AndroidStudio自带工具apksigner对apk重新签名找到apksigner.bat文件 路径D:\…

CentOS7环境下Docker入门到dockerfile(一)CentOS7安装Docker、容器构建、文件复制与挂载

文章目录准备CentOS7虚拟机准备SecureCRT远程连接虚拟机Centos7环境下安装Docker安装Docker镜像Docker容器的基本操作Docker容器的文件复制与挂载可能遇到的问题准备CentOS7虚拟机 关于网络连接三种模式可以参看这篇博客 准备SecureCRT远程连接虚拟机 可以自行搜索相关安装博…

MQTT协议-发布消息和发布确认

MQTT协议-发布消息和发布确认 PUBLISH一发布消息 PUBLISH控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。 发布消息报文由以下5个部分组成 固定报头由两个字节组成&#xff0c;第一个字节的高4位固定为0011&#xff0c;第2位和第1位表示Qos等级&#xff…

Redis单机版安装

文章目录前言Redis单机版安装下载1.安装依赖C语言依赖2.上传并解压3.编译并安装3.1编译3.2安装4.开启守护进程5.启动并测试5.1启动redis5.2关闭/重启redis5.3启动客户端工具5.4杀死进程的方式关闭redis前言 这里安装linux版本的redis,后续如有需要添加windowx版本 安装linux教…

电脑怎么重装系统?教你轻松掌握这些方法

重新安装计算机系统有两种原因&#xff1a;一种是计算机系统可以正常使用&#xff0c;但是电脑比较卡&#xff0c;为了提高它的运行速度&#xff0c;所以想要通过重新安装系统来解决这个问题;另一种原因是计算机系统文件丢失&#xff0c;系统出现蓝屏&#xff0c;或者黑屏的情况…

【Linux内核二】常用的网络丢包错包debug工具介绍

目录 ifconfig Ifconfig输出各字段简述 txqueuelen RX和TX的errors指哪些错误 dropped与overruns的区别 常用ifconfig配置命令 显示网卡信息 启动关闭指定网卡 配置和删除ip地址 修改MAC地址 启用和关闭ARP协议 设置最大传输单元 设置网卡的promiscuous模式 设置…

Git 学习(二)—— 工作区 — 本地仓库的操作命令

我们要上传文件到本地仓库&#xff0c;不是直接拷贝进去的&#xff0c;而是需要通过命令一步步上传。从工作区到本地仓库分为了三步&#xff0c;也可以说是三个区域&#xff1a; 目录 1、操作命令 (1) git init&#xff08;获取本地仓库&#xff09; (2) git add&#xff08;…

【Linux】 -- 进度条小程序

Linux第一个小程序&#xff0d;进度条 目录 行缓冲区概念 \r 和 \n 进度条代码和演示 行缓冲区概念 用两段代码来感受下行缓冲区的存在 #include<stdio.h> …

C++回顾(十四)—— 函数模板

14.1 概述 所谓函数模板(function template)&#xff0c;实际上是建立一个通用函数&#xff0c;其函数类型和形参类型不具体指定&#xff0c;用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替&#xff0c;不必定义多个函数&a…

数据分析方法08用户画像

用户画像 1、 概念 用户画像是指用户信息标签化&#xff0c;通过收集用户多维度的信息数据&#xff08;如人口统计属性&#xff0c;社会属性&#xff0c;行为偏好&#xff0c;消费习惯等&#xff09;&#xff0c;对其进行统计&#xff0c;分析&#xff0c;从而抽象出用户信息…

Ubuntu c++ MySQL数据库操作

mysql安装sudo apt-get install updatesudo apt-get install mysql-server libmysqlclient-dev mysql-workbenchmysql启动/重启/停止sudo service mysql start/restart/stop登录mysql命令&#xff1a;mysql -uroot -p错误异常&#xff1a;解决办法&#xff1a;修改mysqld.cnf配…

软件测试员如何进行产品测试?

一般来讲&#xff0c;当软件成为一个成功的产品后&#xff0c;产品测试工作就会复杂很多。比如拥有的用户量大&#xff0c;迭代频繁&#xff0c;测试的周期短&#xff0c;重复性强。面对紧张复杂的产品测试工作&#xff0c;软件测试员应怎样完成这一系列的测试工作呢&#xff1…

如何修复dxgi.dll文件错误?修复方法推荐

如果您使用Windows操作系统&#xff0c;在使用某些应用程序时&#xff0c;可能会遇到dxgi.dll文件错误。这可能会导致应用程序崩溃或无法正常运行。在本文中&#xff0c;我们将探讨如何修复dxgi.dll文件错误。 一.什么是dxgi.dll文件 dxgi.dll文件是Microsoft DirectX图形接口…

域控制器搭建以及成员加入

需要iso&#xff1a;windows server 2016软件使用&#xff1a;vmwarewindows server 2016系统搭建自己选iso&#xff0c;一直下一步就可以安装完成。&#xff08;记得要设置密码&#xff09;&#xff08;密码要求大小写字母数字符号&#xff09;等待就能安装完成。安装和配置Ac…

day28_js

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 零、 复习昨日 CSS 美化,复用,样式文件和表现文件分离便于维护 选择器 {属性:值;…} 引入css 内联文件内部使用style标签外部文件 <link href"路…

sqoop安装 使用

目录 拷贝安装包 解压 改名 拷贝jar包 修改配置文件 配置环境变量 查看安装情况 查看指定mysql服务器中数据库 查看指定mysql服务器数据库中的表 在hive中创建一个teacher表跟mysql的students中的teacher结构相同 将mysql中students库中的sc数据导出到hdfs指定的文件目…

Spring Cache 介绍及使用方法

目录 一、Spring Cache介绍 1、Spring Cache常用注解 二、Spring Cache使用redis缓存步骤 1、添加依赖 2、添加配置 3、使用注解 一、Spring Cache介绍 Spring cache是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实…

阿里云EMR集群搭建及使用

目录 1.简介 1.什么是EMR 2.组成 3.与自建hadoop集群对比 4.产品架构 2.使用 1.创建EMR集群 1.登录EMR on ECS控制台 2.软件设置 3.硬件设置 3.基础配置 2.配置 1.组件配置 2.用户管理 3.安全组 4.Gateway 3.组件UI 1.简介 1.什么是EMR EMR是运行在阿里云平台…

国际安全领域顶会NDSS 2023录稿整理 (上)

隐私计算研习社 NDSS是网络和系统安全领域的四大顶级国际学术会议&#xff08;BIG4&#xff09;之一&#xff0c;第三十届会议于2023年2月27日到3月3日&#xff0c;在美国圣迭戈举办。本文将分上下两部分整理会议录取的94篇论文&#xff0c;并对论文进行分类&#xff0c;感兴趣…