IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 11. 链表结构和队列 -> 正文阅读

[数据结构与算法]11. 链表结构和队列

常用的数据结构:队列、栈、链表、树等…

  • 队列
    • 先进先出,push shift
    • 举例: 事件环
    • 后进先出,push pop
    • 举例: 方法调用栈、路由切换、浏览器对而历史记录(两个栈)、判断标签是否闭合

1. 栈型结构举例

1.1 方法调用栈

function a(){
  function b(){
    function c(){

    }
    c();
  }
  b();
}
a();
  • 错误的说法:每次执行都会创建一个作用域。
  • 错误的原因:声明时就定义了作用域,而不是执行时创建的。
  • 运行时产生的是执行上下文。这里所谓的栈,就是执行上下文栈。
    • 上面这段代码,执行上下文栈是:[a, b, c],因为先执行的是a,a执行了再执行b,最后是c,所以是a, b, c。但是执行完后,销毁的顺序先是c,等c销毁完了是b,最后是a
    • 上面所说的执行上下问栈,是一层层的关系,并不是包含关系,并不是说c的执行上下文在b的里面,而是说整个执行栈中,c的执行上下文在b的上面

1.2 浏览器的历史记录

  • 有两个栈,假设栈A和栈B
  • 当我进入www.baidu.com时,那么就会在栈A中push,栈A就成了[www.baidu.com]
  • 这时我再进去www.taobao.com时,那么就会在栈A中再push,栈A就成了[www.baidu.com, www.taobao.com]
  • 然后这时候我按浏览器后退键,那么栈A就会pop,栈A就成了[www.baidu.com],这时候栈B就会push进栈A出来的网站,也就是栈B变成了[www.taobao.com]
  • 如果这时候按前进,B就会pop,将pop出的给栈A,也就是A会push进去。再按后退,A就会pop出去,B会push进A出来的网站。
  • 经过上面一系列操作后,这时候栈A是[www.baidu.com],栈B是[www.taobao.com]。如果这时候在浏览器输入www.jd.com,那么栈B就会被清空,栈A就会push进www.jd.com,也就是A变成了[www.baidu.com, www.jd.com],栈B就成了[]
  • 这时候你前进后退就跟之前一样了
    在这里插入图片描述

1.3 判断标签是否闭合

  • 比如有
  • 当我遇到开始标签的时候,就往栈中push,如上面就是[div, span]
  • 当我遇到结束标签的时候,就从栈中pop,比如上面先遇到,那么栈就成了[div],又遇到,就栈就成了[]
  • 最后如果栈是空的,那么说明这段html中所有标签都是闭合的,否则就是有问题的,当然单标签除外。

2. 手写一个链表结构

  • 数组的shift是比较浪费性能的,每次弹出一个后续内容都会前进,所以这时候就需要链表(通过指针连接起来)

  • 链表查找、删除的性能平均复杂度是O(n),跟数组遍历复杂度一样的,都是O(n)。但是链表可以优化头尾操作,比较合适。

  • 我们可以使用链表来实现 栈 或 队列
    在这里插入图片描述

  • 链表的实现:

class Node{
  constructor(element, next){
    this.element = element; // 节点元素
    this.next = next; // 指向下一个的指针
  }
}

// 链表类
class LinkedList{
  constructor(){
    this.head = null; // 链表的头
    this.size = 0; // 链表的大小
  }
  // 增加
  add(index, element){
    if (arguments.length === 1) {
      element = index; // 如果参数只有一个,那么相当于向链表最后一个添加。这时候,第一个参数其实就是元素值
      index= this.size;
    }
    if (index < 0 || index > this.size) throw new Error('链表索引异常');

    if (index === 0) {
      let oldHead = this.head;
      this.head = new Node(element, oldHead) // element是当前节点,oldHead老的节点就成为下一个节点了
    } else {
      let preNode = this.getNode(index - 1);
      preNode.next = new Node(element, preNode.next); // 上一个的next指向新增的元素,新增的元素的next指向原先上一个的next
    }


    this.size++; // 每次添加完,长度应该加1
    // console.log(index, element)
  }
  // 删除
  remove(index){
    if (index < 0 || index >= this.size) throw new Error('链表索引异常');
    let oldNode = null;
    if (index === 0) {
      oldNode = this.head;
      this.head = oldNode && oldNode.next;
    } else {
      let prevNode = this.getNode(index - 1);
      oldNode = prevNode.next;
      prevNode.next = prevNode.next.next;
    }
    this.size--;
    return oldNode && oldNode.element; // 返回删除的元素
  }
  // 查找,获取某个节点
  getNode(index){
    let current = this.head; // 从头开始找
    for(let i = 0; i < index; i++) {
      current = current.next;
    }
    return current;
  }
  // 获取链表的长度,节点的总个数
  length(){
    return this.size;
  }
}

module.exports = LinkedList;

3.将列表封装成队列

const LinkedList = require('./6.链表结构');

// 将链表进行封装,封装成队列
class Queue{ // 队列主要是添加和删除
  constructor(){
    this.ll = new LinkedList();
  }
  offer(element){ // 入队列
    this.ll.add(element);
    return this;
  }
  poll(){ // 出队列,也就是从头部删除
    this.ll.remove(0);
    return this;
  }
  getQueue(){
    let queue = [];
    for(let i = 0; i < this.ll.length(); i++) {
      let current = this.ll.getNode(i).element;
      queue.push(current)
    }
    return queue;
  }
}

module.exports = Queue;
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-02 11:37:50  更:2021-09-02 11:40:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:37:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码