数据结构

数据结构是计算机底层存储、组织数据的方式

是指数据相互之间是以什么方式排列在一起的

数据结构是为了更加方便的管理和使用数据,需要结合具体的业务场景来进行选择

一般情况下,精心选择的数据结构可以带来更高的运行或存储效果

常见的数据结构

  • 队列
  • 数组
  • 链表
  • 二叉树
  • 二叉查找树
  • 平衡二叉树
  • 红黑树

重点掌握:

  1. 数据结构的样式
  2. 如何添加数据
  3. 如何删除数据

数据结构(栈)

栈的特点:后进先出,先进后出

数据进入栈模型的过程称为:压栈/进栈

数据离开栈模型的过程称为:弹栈/出栈

栈内最后进入的元素(处于顶部的元素)称为栈顶元素

栈内最先进入的元素(处于底部的元素)称为栈底元素

数据结构(队列)

队列的特点:先进先出,后进后出,将数据进入的一端称为后端,数据出去的一端称为前端

数据从后端进入队列模型的过程称为:入队列

数据从前端离开队列模型的过程称为:出队列

数据结构(数组)

  • 查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同(元素在内存中是连续存储的)
  • 删除效率低:要将原始数据删除,同时后面每个数据前移
  • 添加效率极低:添加位置后的每个数据后移,再添加元素

数据结构(链表)

链表内的每一个元素都称为结点,每一个结点都是一个对象

结点中,会存储如下内容:

  • 存储具体的数据
  • 地址值
  • 下一个结点的地址(当不存在下一个结点时,地址为空)

链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址

特点:

链表查询慢,无论查询哪个数据都要从头开始找

链表的增删相对快(只需要修改对应结点记录的地址值)

以上就是最基础的单向链表,还有一种链表为双向链表,即结点中存储三个部分:数据、前一个结点的地址、后一个结点的地址

数据结构(树)

示例:

其中,16可以看作是15、17的父节点,15是16的左子节点,17是16的右子节点

每一个结点都会存储四个值,分别是:

  1. 数据
  2. 父节点地址
  3. 左子节点地址
  4. 右子节点地址

若是没有父节点地址、子节点地址,记为null

度:每一个节点的子节点数量

树高:树的总层数(示例中,树的高度为4)

根节点:最顶层的结点(示例中,树的根为22)

左子节点:左下方的节点

右子节点:右下方的结点

根节点的左子树:就是根节点的左子节点以及子子节点(示例中,左子树为18、16、20、15、17、19、12)

根节点的右子树:就是根节点的右子节点以及子子节点(示例中,左子树为26、24、28、23、25、27、29)

数据结构(二叉树)

二叉树中,任意节点的度<=2

普通的二叉树

排列没有规则

数据结构(二叉查找树)

二叉查找树,又称二叉排序树或者二叉搜索树

特点:

  1. 每个节点上最多有两个子节点
  2. 任意节点左子树上的值都小于当前节点
  3. 任意节点右子树上的值都大于当前节点

规则:小的存左边,大的存右边,一样的不存

数据结构(平衡二叉树)

规则:任意节点左右子树高度差不超过1

示例:

假设要查询数据10,效率太低。此时需要平衡二叉树

示例:

旋转机制

规则1:左旋

规则2:右旋

触发时机:当添加一个节点后,该树不再是一棵平衡二叉树

左旋

确定支点:从添加的节点开始,不断的往父节点找不平衡的节点

步骤:

  1. 以不平衡的点作为支点
  2. 把支点左旋降级,变成左子节点
  3. 晋升原来的右子节点

不平衡二叉树示例1:

以上图例,不平衡点为10

将10作为左子节点,再晋升11、12

经过左旋后的平衡二叉树:

不平衡二叉树示例2:

此时,不平衡点就不再是10,而是根节点7

且左旋的步骤也发生了改变:

  • 以不平衡点为支点
  • 将根节点的右侧往左拉
  • 原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点

经过左旋后的平衡二叉树:

右旋

确定支点:从添加的节点开始,不断的往父节点找不平衡的节点

步骤:

  1. 以不平衡的点作为支点
  2. 把支点右旋降级,变成右子节点
  3. 晋升原来的左子节点

使用方法和左旋类似

平衡树需要旋转情况
  1. 左左
  2. 左右
  3. 右右
  4. 右左
左左

当根节点左子树的左子树有节点插入,导致二叉树不平衡

节点插入前的平衡二叉树:

左左,在根节点左子树的左子树插入节点,导致不平衡二叉树:

一次右旋就可以保持平衡:

左右

当根节点左子树的右子树有节点插入,导致二叉树不平衡

节点插入前的平衡二叉树:

左右,在根节点左子树的右子树插入节点,导致不平衡二叉树:

先在局部进行左旋,使其成为左左

再整体右旋

右右

当根节点右子树的右子树有节点插入,导致二叉树不平衡

节点插入前的平衡二叉树:

右右,在根节点右子树的右子树插入节点,导致不平衡二叉树:

一次左旋就可以保持平衡:

右左

当根节点右子树的左子树有节点插入,导致二叉树不平衡

节点插入前的平衡二叉树:

右左,在根节点右子树的左子树插入节点,导致不平衡二叉树:

局部右旋

再整体左旋

总结

左左和右右只需一次旋转就可以保持平衡,而左右和右左需要进行局部旋转,再整体旋转才能保持平衡

二叉树遍历方式

前序遍历:

从根节点开始,然后按照当前节点,左子节点,右子节点的顺序遍历

示例:

遍历获取元素顺序为:20 ➡ 18 ➡ 16 ➡ 19 ➡ 23 ➡ 22 ➡ 24

中序遍历:

从最左边的子节点开始,然后按照左子节点,当前节点,右子节点的顺序遍历

遍历获取元素顺序为:16 ➡ 18 ➡ 19 ➡ 20 ➡ 22 ➡ 23 ➡ 24

后序遍历:

从最左边的子节点开始,然后按照左子节点,右子节点,当前节点的顺序遍历

遍历获取元素顺序为:16 ➡ 19 ➡ 18 ➡ 22 ➡ 24 ➡ 23 ➡ 20

层序遍历:

从根节点开始,一层一层的遍历

遍历获取元素顺序为:20 ➡ 18 ➡ 23 ➡ 16 ➡ 19 ➡ 22 ➡ 24

总结:

  1. 前序遍历:当前节点,左子节点,右子节点
  2. 中序遍历:左子节点,当前节点,右子节点
  3. 后序遍历:左子节点,右子节点,当前节点
  4. 层序遍历:一层一层的去遍历

二叉树的演变

二叉树 ➡ 二叉查找树 ➡ 平衡二叉树

查找效率:从左往右,从小到大

数据结构(红黑树)

  • 红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构
  • 1972年出现,当时被称为平衡二叉B树。直到1978年,被正式修改为如今的红黑树
  • 它是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色
  • 每一个节点可以是红或者黑;红黑树不是高度平衡的,它的平衡是通过红黑规则进行实现的

红黑规则

  1. 每一个节点或是黑色的,或者是红色的
  2. 根节点必须是黑色
  3. 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点是黑色的
  4. 如果某个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)
  5. 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

示例:

节点添加规则

默认颜色:添加节点默认是红色的(效率高)

红黑树旋转时,不需要将Nil叶节点进行旋转

红黑树增删改查的性能都很好