数据结构与算法:栈和队列

1 栈

栈是一种后入先出(LIFO)的线性逻辑存储结构。只允许在栈顶进行进出操作。

1.1 栈基本操作

基本操作包括:入栈(push)/出栈(pop)/获取栈顶元素(peek)。

栈的实现主要有两种: 1. 数组实现,即顺序栈 2. 链表实现,即链式栈

无论是以数组还是以链表实现,入栈、出栈的时间复杂度都是O(1)。

栈的应用比如函数执行/括号匹配/表达式计算/浏览器前进后退。

   

1.2 设计栈

1.2.1 数组实现栈

class ArrayStack<T> {items: T[];constructor() {this.items = [];}/*** 入栈* @param item*/push(item: T) {this.items.push(item);}/*** 出栈* @returns*/pop() {if (this.isEmpty()) throw new Error('栈空');return this.items.pop();}/*** 获取栈顶元素* @returns*/peek() {if (this.isEmpty()) throw new Error('栈空');return this.items[this.items.length - 1];}/*** 判空* @returns*/isEmpty() {return this.items.length === 0;}/*** 获取栈元素的个数* @returns*/getSize() {return this.items.length;}
}

1.2.2 链表实现栈

class LinkStack<T> {// 栈的长度size: number;// 栈顶指针top: LinkNode<T> | null;constructor() {this.size = 0;this.top = null;}/*** 入栈* @param item*/push(val: T) {let node = new LinkNode(val);if (this.top === null) {// 栈空this.top = node;} else {// 栈非空node.next = this.top;this.top = node;}this.size = this.size + 1;}/*** 出栈* @returns*/pop() {if (this.top === null) {// 栈空throw new Error('栈空');} else {// 栈非空const data = this.top.val; // 栈顶元素值this.top = this.top.next; // 新栈顶this.size = this.size - 1;return data;}}/*** 获取栈顶元素* @returns*/peek() {if (this.top === null) {// 栈空throw new Error('栈空');} else {return this.top.val;}}/*** 判空* @returns*/isEmpty() {return this.top === null;}/*** 获取栈元素的个数* @returns*/getSize() {return this.size;}
}

1.3 剑指 offer 栈算法题( typescript 版)

包含min函数的栈

栈的压入、弹出序列

2 队列

队列是一种先入先出(FIFO)的线性逻辑存储结构。只允许在队首进行出队(即delete删除)操作,队尾进行入队(即insert插入)操作。

2.1 队列基本操作

队列的基本操作包括:入队 (enqueue)/ 出队 (dequeue)/ 获取队头元素(peek)

队列的实现主要有两种: 1. 数组实现,即顺序队列 2. 链表实现,即链式队列。

无论是以数组还是以链表实现,入队、出队的时间复杂度都是O(1)。

队列的应用比如线程池、资源池、消息队列、异步队列。

2.2 设计队列

2.2.1 数组顺序队列

使用数组实现,使用shift出队时每次都要移动队列元素,效率不高。改进方案是可以队列初始化时就需要规定队列长度通过判断队尾是否有空间,有就让元素一直入队,直到队尾没有空间位置,然后进行整体进行一次搬移,这样优化了入队的效率,平均时间复杂度还是 O(1)。

class ArrayQueue<T> {items: T[];constructor() {this.items = [];}/*** 入队* @param item*/push(item: T) {this.items.push(item);}/*** 出队* @returns*/pop() {if (this.isEmpty()) throw new Error('队列空');return this.items.shift();}/*** 获取队顶元素* @returns*/peek() {if (this.isEmpty()) throw new Error('队列空');return this.items[0];}/*** 判空* @returns*/isEmpty() {return this.items.length === 0;}/*** 获取队元素的个数* @returns*/getSize() {return this.items.length;}
}

2.2.2 数组循环队列

数组实现,初始化需指定队列容量capacity,留一个空位,队空条件 head = tail,队满条件 head =( tail + 1) % capacity,队列元素个数(tail - head + capacity) % capacity)。

class LoopQueue {// 存放元素的数组values: (number | undefined)[];// 当前元素个数count: number;// 队的长度capacity: number;// 队尾head: number;// 队尾tail: number;constructor(capacity: number) {this.head = 0;this.tail = 0;this.capacity = capacity;this.count = 0;this.values = new Array(capacity);}/*** 入队* @param item*/enQueue(val: number) {if (this.isFull()) {throw new Error('队满');}this.values[this.tail] = val;this.tail = (this.tail + 1) % this.capacity;this.count = this.count + 1;return true;}/*** 出队* @returns*/deQueue(): number {if (this.isEmpty()) {throw new Error('队空');}const value = this.values[this.head] as number;this.values[this.head] = undefined;this.head = (this.head + 1) % this.capacity;this.count = this.count - 1;return value;}/*** 获取队头元素* @returns*/peek() {if (this.isEmpty()) {throw new Error('队空');}const value = this.values[this.head];return value;}/*** 判空* @returns*/isEmpty() {// 或 return this.head === this.tailreturn this.count === 0;}/*** 判满* @returns*/isFull() {// 或 return this.head === (this.tail + 1) % this.capacityreturn this.count === this.capacity - 1;}/*** 获取队元素的个数* @returns*/getSize() {return this.count;}/*** 清空队列* @returns*/clear() {this.head = 0;this.tail = 0;this.count = 0;this.values = new Array(this.capacity);return true;}
}

2.2.3 链式顺序队列

链表实现,链表尾入队,链表头出队

class LinkQueue<T> {// 队的长度size: number;// 队尾指针head: LinkNode<T> | null;// 队尾指针tail: LinkNode<T> | null;constructor() {this.size = 0;this.head = null;this.tail = null;}/*** 入队* @param item*/enQueue(val: T) {let node = new LinkNode(val);if (this.size === 0) {this.head = node;this.tail = node;} else {this.tail!.next = node;this.tail = this.tail!.next;}this.size = this.size + 1;}/*** 出队* @returns*/deQueue() {if (this.size === 0) {// 队空throw new Error('队空');} else {// 队非空const node = this.head;this.head = node!.next;this.size = this.size - 1;return node!.val;}}/*** 获取队头元素* @returns*/peek() {if (this.size === 0) {// 队空throw new Error('队空');} else {return this.head!.val;}}/*** 判空* @returns*/isEmpty() {return this.size === 0;}/*** 获取队元素的个数* @returns*/getSize() {return this.size;}
}

2.3 剑指 offer 队列算法题( typescript 版)

两个栈实现队列

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot2+Vue2实战(四)进行组件内容拆分及路由实现

一、拆分 新建包&#xff1a; Aside和Header都是组件 User为视图 Aside.vue&#xff1a; <template><el-menu :default-openeds"[1, 3]" style"min-height: 100%; overflow-x: hidden"background-color"rgb(48, 65, 86)"text-color…

【Flume】高级组件之Sink Processors及项目实践(Sink负载均衡和故障转移)

文章目录 1. 组件简介2. 项目实践2.1 负载均衡2.1.1 需求2.1.2 配置2.1.3 运行 2.2 故障转移2.2.1 需求2.2.2 配置2.2.3 运行 1. 组件简介 Sink Processors类型包括这三种&#xff1a;Default Sink Processor、Load balancing Sink Processor和Failover Sink Processor。 Defa…

供应商索赔(金税数据)导入并创建凭证(ALV长篇备忘三)

情境/背景:供应商三包索赔款项源起QMS质量系统&#xff0c;联动金税系统完成发票开具&#xff0c;最终在SAP系统中创建完成财务凭证。该流程为手工操作&#xff0c;费时费力且效率低下容易出错。 目标/任务:把QMS供应商三包索赔业务搬上线,同SAP FI顾问梳理功能说明书&#xf…

星辰秘典:揭开Python项目的神秘密码——2048游戏

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;html css js&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;你好&#x…

一步一步学OAK之七:通过OAK相机实现特征跟踪

目录 特征跟踪Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 定义FeatureTrackerDrawer类定义变量定义onTrackBar方法定义trackFeaturePath方法定义drawFeatures方法定义FeatureTrackerDrawer类的构造函数 Setup 5: 创建pipelineSetup 6: 创建节点创建相机…

GIT保存记录原理之commit对象

GIT 中提交对象非常的重要&#xff0c;我们通过它记录代码提交过程、进行文件保存、回退等操作&#xff0c;那么它是怎样帮助我们记录这些信息的呢&#xff1f;其实就是都保存在项目根目录的 .git 文件夹中。 新建空项目 gitDemo使用 git init初始化&#xff0c;在文件夹根目录…

图像去模糊:RSBlur 数据集以及模糊图像合成方法

本内容主要介绍图像去模糊数据集 RSBlur&#xff0c;以及逼真模糊图像合成方法。 论文&#xff1a;Realistic Blur Synthesis for Learning Image Deblurring 代码&#xff08;官方&#xff09;&#xff1a;https://github.com/rimchang/RSBlur 1.1 背景 运动模糊是由曝光…

vue 组件简单实例及传参交互

前言:vue 可以比较灵活的使用 html的片段&#xff0c;并将html的片段进行数据隔离&#xff0c;参数也可以互相传递&#xff0c;组件与组件之间也可以进行数据的交互 合理的使用组件可以避免重复代码或者很方便的调用第三方组件库 vue组件 简单实例组件传参实际应用父子组件交互…

maven打包所有依赖,对外提供sdk.jar

maven打包所有依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compile.source>1.8</maven.compile.source><maven.compile.target>1.8</maven.compile.target></properties><…

分布式计算模型详解:MapReduce、数据流、P2P、RPC、Agent

前言 本文隶属于专栏《大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据理论体系 思维导图 MapReduce MapReduce 是一种分布式计算模…

在 Maya、ZBrush、Substance 3D 和 UE5 中创建理发椅

今天瑞云渲染小编给大家带来Kevin J. Coulman 分享的理发椅项目背后的工作流程&#xff0c;详细介绍了如何在 Maya 和 ZBrush 中为道具建模&#xff0c;分享了制作准确材质的技巧&#xff0c;并解释了为什么选择 UE5 进行渲染。 介绍 大家好! 我的名字是Mehdi Benmansour&…

layui实现选择框搜索(下拉搜索)功能

1.可以使用官方介绍的方法&#xff0c;适用于form表单内的下拉搜索&#xff0c;外层需要使用layui-form样式&#xff0c;select标签内添加lay-search“”&#xff0c;此方法若外层不添加layui-form无法实现搜索功能&#xff0c;如下所示&#xff1a; 2.下面是另一种形式的下拉选…