数据结构-分类

187 阅读7分钟

数据结构与算法

  • 本文件内所有知识点均是基础的数据结构与算法,具体参考每个章节markdown
  • 后续深入理解,参考 初级算法 && 中级算法 && 高级算法 (大部分参考leetCode)

数据结构

  • 栈: 一种遵从先进后出原则的有序集合;新添加或者待删除的元素都会保存的在栈的头部,称为栈顶,另一端为栈底,在栈里面,新元素都靠近栈顶,旧元素都接近栈底
  • 队列: 与栈相反,遵从先进先出的原则的一组有序的项,队列在尾部添加新的元素,并从头部移除元素,最新添加的元素必须在队列的末尾
    • 普通队列
    • 优先队列
    • 循环队列
  • 链表: 存储有序的元素集合, 但不同与数组, 链表中元素在内存中并不是连续放置的; 每个元素由一个存储元素本身的节点和一个指向下一个元素引用(指针/链接)组成
    • 普通链表
    • 双向链表
    • 循环链表
  • 集合: 集合是一组无序且唯一的项组成,这个数据结构使用了与有限集合相同的数学概念
  • 字典: 集合、字典、散列表都可以存储不重复的数据,字典和集合很像,集合是以{value: value}形式存储数据,而字典是以{key: value}形式存储数据,字典也称为映射(object对象便是字典在javascript中的实现)
  • 散列: HashMap类是Dictionary的一种散列表实现方式, 散列算法是尽可能地在数据结构中快速找到一个值,使用散列函数,就知道 值的具体位置,因此能够快速检索到該值,散列函数的作用是给定一个键值,然后返回值在表中的地址。
  • 树: TODO

一种遵从先进后出原则的有序集合;新添加或者待删除的元素都会保存的在栈的头部,称为栈顶,另一端为栈底,在栈里面,新元素都靠近栈顶,旧元素都接近栈底
栈也被用在编程语言的编辑器和内存中保存变量,方法调用

队列

在现实中,最常见的例子就是排队,吃饭排队、银行业务排队、公车的前门上后门下机制...,前面的人优先完成自己的事务,完成之后,下一个人才能继续。总之,遵从先出原则,

优先队列

其中一个修改版就是优先队列。元素的添加和移除是基于优先级的。一个现实的例子就是机场登机的顺序。头等舱和商务舱乘客的优先级要高于经济舱乘客。在有些国家,老年人和孕妇(或 带小孩的妇女)登机时也享有高于其他乘客的优先级。

循环队列

为充分利用向量空间, 克服"假溢出"现象的方法是: 将向量空间想象成一个首尾相接的圆环,并称为这种向量为循环向量,存储在其中的队列称为循环队列,这种循环队列可以以单链表, 队列的方式在实际编程中应用中实现

链表

存储有序的元素集合, 但不同与数组, 链表中元素在内存中并不是连续放置的; 每个元素由一个存储元素本身的节点和一个指向下一个元素引用(指针/链接)组成

普通链表

数组的大小是固定的, 从数组起点或中间插入或移除项成本很高,以为需要移动元素
链表存储有序的集合,但不同与数组,链表中元素在内存中并不是连续放置的,每个元素由一个存储元素本身的节点和一个指向下一个元素引用(指针/链接)组成
1、相对于传统数组,链表在于,添加或者删除元素不需要移动其他元素,改变元素之间的引用即可
2、数组的另一个细节是可以直接访问任何位置的元素,而要想访问链表中间的一个元素,需要从起点开始迭代直到找到所需的元素

双向链表

概念: 链表是双向,node一个链向下一个元素,一个链向上一个元素
在普通链表中在迭代元素过程中如果错过迭代元素那么就得重新开始,但是在双向链表中,由于双向指向,不必每次重新循环迭代,打打节省了内存消耗

循环链表

循环链表可以像普通链表一样只有单项引用,也可以像双向链表一样有双向引用,循环链表和普通链表之间唯一区别的就是,最后一个元素指向下一个元素的引用而不是null,指向第一个(head)
双向循环链表 head的previous指向了tai

双向循环链表

综合了双向链表以及循环链表的特点

集合

目前es6已内置Set类型的实现, 下面将手动实现实现一个集合类
对集合可以进行如下操作

  • 并集: 对于给定2个集合,返回一个包含2个集合所有元素的集合
  • 交集: 对于给定2个集合,返回一个2个集合都包含元素的集合
  • 差集: 对于给定2个集合, 返回包含在A集合但不包含于B集合的新集合
  • 子集: 验证一个集合是不是全部包含在另一个集合中

字典

集合、字典、散列表都可以存储不重复的数据,字典和集合很像,集合是以{value: value}形式存储数据,而字典是以{key: value}形式存储数据,字典也称为映射(object对象便是字典在javascript中的实现)

散列

HashMap类是Dictionary的一种散列表实现方式, 散列算法是尽可能地在数据结构中快速找到一个值,使用散列函数,就知道 值的具体位置,因此能够快速检索到該值,散列函数的作用是给定一个键值,然后返回值在表中的地址

树是一种非顺序数据结构,一种分层数据的抽象模型,它对于储存需要快速查询的数据非常有用
一个树结构包含一系列存在父节点关系的节点(除了顶部的第一个节点)以及零个或者多个子节点
树大概包含以下几种数据特性

  • 节点
    -根节点
    -内部节点:非根节点、且有子节点的节点
    -外部节点/页节点:无子节点的节点
  • 子树:就是大大小小节点组成的书
  • 深度:节点到根节点的节点数量
  • 高度:树的高度取决节点深度的最大值
  • 层级: 也可以按照节点级别来分层
二叉树和二叉树搜索树
  • 二叉树中的节点最多只能有2个节点,一个是左侧的子节点,另一个是右侧的子节点。
  • 二叉搜索树是二叉树的一种,但是它只允许你在左侧节点存储比父节点小的值,在右侧节点存储大于或者等于父节点的值
  • 不同之前的链表和集合,在树中节点被称为“键”,而不是“项”

树的遍历:中序、先序、后序

  • 中序:中序遍历是一种以上行访问BST所有节点的遍历方式,也就是最小到最大的顺序访问节点,中序遍历是一种应用对树的排序操作
  • 先序遍历是优先与后代节点顺序访问每个节点的,先序遍历的一种应用是打印结构化文档
  • 后续遍历则是访问后代节点,在访问节点本身,后续遍历是一种应用计算的一个目录和它的子目录的所有文件所占的大小

三种遍历方式的不同:

  • 先序遍历: 节点本身 => 左侧子节点 => 右侧子节点
  • 中序遍历: 左侧子节点 => 右侧子节点 => 节点本身
  • 后续遍历: 左侧子节点 => 节点本身 => 右侧子节点