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

news2024/11/25 12:26:12

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.tail
    return this.count === 0;
  }
  /**
   * 判满
   * @returns
   */
  isFull() {
    // 或 return this.head === (this.tail + 1) % this.capacity
    return 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.coloradmin.cn/o/702728.html

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

相关文章

CNN卷积类型总结(标准卷积、空洞卷积、反卷积、深度可分离卷积、分组卷积等)

目录 标准卷积 卷积的运算 conv2d conv1d 其他卷积类型 空洞卷积&#xff08;膨胀卷积&#xff09; 反卷积&#xff08;转置卷积&#xff09; 深度可分离卷积 分组卷积 参考文章 上学时&#xff0c;卷积常在各个课程中出现&#xff0c;现代、信号与系统这些&#xff…

第45步 深度学习图像识别:Nasnet建模(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Nasnet NASNet是由Google Brain团队在2017年提出的一种神经网络架构搜索&#xff08;Neural Architecture Search&#xff0c;简称NAS&#xff09;的结果。NAS是一种用于自动化设计深度学习模型的技术。在NA…

oracle字符集

1、查看oracle字符集 如果操作系统或者客户端的字符集设置和数据库设置不一样就会出现乱码 查询NLS_LANG即操作系统环境变量要设为 NLS_LANGUAGE_NLS_TERRITORY**.NLS_CHARACTERSET**&#xff0c;如&#xff1a; export NLS_LANG“AMERICAN_AMERICA.AL32UTF8”

Spring MVC处理响应附案例详解

目录 一、配置视图解析器 二、控制器方法的返回值 2.1 返回值为void 2.1.1 控制器方法 2.1.2 jsp页面 2.1.3 测试结果 2.2 返回值为String 2.2.1 控制器方法 2.2.2 测试结果 2.3 返回值为ModelAndView 2.3.1 控制器方法 2.3.2 JSP页面 2.3.3 测试结果 三、某些会…

基于蒙特卡罗法评估智能电网可靠性研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

python爬虫_django+vue+echarts可视化查询所有CSDN用户质量分

文章目录 ⭐前言⭐ 效果⭐django简介⭐vue3简介⭐vue引入echarts ⭐前后分离实现&#x1f496; django代码层&#x1f496; vue3代码层结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前后分离djangovueecharts可视化查询CSDN用户质量分。 该系列文章&#…

一种基于linux内核双向链表的移植

1.简介 双向链表&#xff08;Doubly Linked List&#xff09;是一种常见的数据结构&#xff0c;由一系列的节点组成&#xff0c;每个节点都包含两个指针&#xff0c;分别指向前一个节点和后一个节点。与单向链表不同&#xff0c;双向链表可以在 O(1) 的时间复杂度内向前或向后遍…

【Unity编辑器扩展】(三)PSD转UGUI Prefab, 一键拼UI解放美术/程序(完结)

工具效果&#xff1a; 第一步&#xff0c;把psd图层转换为可编辑的节点树&#xff0c;并自动解析UI类型、自动绑定UI子元素&#xff1a; 第二步, 点击“生成UIForm"按钮生成UI预制体 (若有UI类型遗漏可在下拉菜单手动点选UI类型)&#xff1a; 验证一键生成UI效果: 书接上…

idea双击打不开怎么办?

今天在敲代码的时候&#xff0c;突然出现了一个bug&#xff0c;idea打不开了&#xff0c;这个问题怎么解决&#xff1f; 只要找到C:\Users\Administrator .IntelliJIdea2019.3这个文件把所有文件都给删了就可以重启了 哈哈&#xff0c;重启成功

Bayes贝叶斯定理

问题的关键在于&#xff1a;人们是否考虑过大背景/先验/问题的前提&#xff0c;从而做出一个大致的估计。这就引出了我们关于理性的探讨&#xff0c;理性不是说知道事实&#xff0c;而是认识到哪些因素是有关的。 x.1 一个关于贝叶斯定理的例子 引入一个steve假设。我们已知大…

开源进展 | WeIdentity v3.1.1发布,提供无存储依赖的纯功能接口

作为连接实体对象&#xff08;人或物&#xff09;的现实身份与链上身份的可信映射&#xff0c;实现实体对象之间安全可信的数据授权与交换&#xff0c;分布式身份技术解决方案在推动区块链应用繁荣及可信数据流转的过程中扮演着重要角色。 WeIdentity是由微众银行自主研发并完全…

parcel打包工具搭建热开发项目环境

parcel是一款WEB端打包工具 能够提供热开发的项目环境 使用了的话不然Webpack 但相对搭建项目会更快一些 我们现在本地创建一个目录 然后 用编辑器打开我们创建的目录 运行终端 在终端中输入 npm init 初始化一个项目 运行完毕之后 我们就会得到一个package.json文件 然后…

Spring Boot 中的 RedisCacheManager 是什么,原理,如何使用

Spring Boot 中的 RedisCacheManager 是什么&#xff0c;原理&#xff0c;如何使用 介绍 在现代应用程序中&#xff0c;缓存是提高应用程序性能的重要组成部分。Spring Boot 提供了一个强大的缓存框架&#xff0c;它支持多种缓存提供程序&#xff0c;包括 Redis、Ehcache、Ca…

国金QMT量化交易系统的Bug及应对策略

国金QMT量化交易系统中的 账号成交状态变化主推 deal_callback() &#xff0c; 当账号成交状态有变化时&#xff0c;这个函数被客户端调用。 我的策略是&#xff0c;在handlebar()里面挂单&#xff0c;等待成交&#xff0c;而判断成交的方式是根据系统主推deal_callback()通知…

数据结构与算法:查找、排序、动态规划、数学

1 查找表 查找表是同一数据类型构成的集合。只进行查找操作的称为静态查找表&#xff1b;在查找的同时进行插入和删除操作的称为动态查找表。 查找算法衡量好坏的依据为&#xff1a;查找成功时&#xff0c;查找的关键字和查找表中比较过的数据元素的个数的平均值&#xff0c;…

MKS SERVO4257D 闭环步进电机_系列10 arduino 例程

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口&#xff0c;支持MODBUS-RTU通讯协议&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&a…

HiEV独家|余承东力推L3标准,华为ADS更高阶产品将至

作者 | 张祥威 编辑 | 德新 L3标准出台提速&#xff0c;智驾江湖的厮杀将更加惨烈。 近日&#xff0c;多位接近华为的人士告诉HiEV&#xff0c;余承东正在力推自动驾驶L3标准尽快出台&#xff0c;华为的多位技术专家深度参与了L3标准制定。 本月稍早前&#xff0c;余承东在重庆…

计算机网络-数据链路层下篇

目录 计算机网络 七、MAC地址&#xff0c;IP地址及ARP地址 &#xff08;一&#xff09;MAC地址 &#xff08;二&#xff09;IP地址 &#xff08;三&#xff09;ARP地址 八、集线器和交换机的区别 九、以太网交换机自学习和转发帧的流程 十、以太网交换机的生成树协议ST…

一步一步学OAK之十三:实现RGB相机上的空间对象跟踪

前面我们实现了在RGB相机上进行物体的对象跟踪&#xff0c;能够实时跟踪我们想要追踪的物探&#xff0c;但是&#xff0c;如果我们要想知道这个物体的三维空间坐标&#xff0c;该如何实现呢&#xff1f;要想实现这个功能&#xff0c;我们需要用到DepthAI API提供的MobileNetSpa…

无人机动力测试台-50公斤级-Flight Stand 50

Flight Stand 50测试台通过测量电机和螺旋桨的拉力、扭矩、转速、电流、电压、温度、螺旋桨效率和电机效率来精准地描述和评估无人机动力系统的性能。 产品应用 Flight Stand 50测试台可以用于以下方向&#xff1a; 实时动态测试 FS50 Pro的1000 Hz采样率使测试成为可能&am…