目录
(3)拉链法导致的链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?
数据结构是工具,算法是通过合适的工具解决特定问题的方法。
一、线性表
数据结构底层存储方式只有两种:数组(顺序存储)和链表(链式存储)。
1、顺序存储
(1)定义
用一组地址连续的存储单元依次存放线性表的元素。
(2)原理
数组
(3)线性表基本操作
- 初始化
- 返回线性表长度
- 判断线性表是否为空
- 清空线性表
- 获取指定索引处的元素(查)
- 按值查找数据元素的位置(查)
- 直接插入数据元素(增)
- 向指定位置插入数据元素(增)
- 直接删除数据元素(删)
- 删除线性表中指定位置的数据元素(删)
(4)Java实现
- ArrayList
2、链式存储
(1)定义
采用一组地址任意的存储单元存放线性表中的数据元素。
(2)原理
节点 = 数据元素 + 引用下一个节点的引用 + 引用上一个节点的引用
(4)Java实现
- LinkedList
顺序存储和链式存储区别
空间性能 | 时间性能 | |
顺粗存储 | 顺序存储的空间是静态分布的,需要一个长度固定的数组,因此总有部分数组元素被浪费。 | 顺序存储中的元素的逻辑顺序与物理存储顺序保持一致,而且支持随机存储,因此查找读取时性能好。 |
链式存储 | 链表的存储空间是动态分布的,因此空间不会被浪费。但由于链表需要额外空间来为每个节点保存指针,因此也需要牺牲一部分空间。 | 链表采取链式结构来保存表内元素,因此插入、删除元素时性能较好。 |
二、栈和队列
1、栈
(1)定义
栈是一种特殊的线性表,只能在固定一端进行插入或删除操作。
(2)原理
(3)操作
- 初始化
- 返回栈的长度
- 入栈
- 出栈
- 访问栈顶元素
- 判断栈是否为空
- 清空栈
(4)Java实现
- Stack:数组实现,线程安全
- LinkedList:双端链表,线程不安全
- ArrayDeque:顺序存储结构双端队列,线性不安全,Java推荐并使用Collections包装成线程安全
2、队列
(1)定义
队列是一种被限制过的线性表,它使用固定的一端来插入元素,另一端只用于删除元素。
(2)原理
(3)操作
- 初始化
- 返回队列长度
- 入队
- 出队
- 访问队列的前端元素
- 判断队列是否为空
- 清空队列
(4)Java实现
- ArrayDeque:顺序存储结构双端队列
- LinkedList:链式存储结构双端队列
三、二叉树
1、定义
二叉树指的是每个节点最多只能有两个子树的有序树。
2、性质
- 二叉树第 i 层上的节点数目至多为( i ≥ 1 );
- 深度为 k 的二叉树至多有个节点;
- 在任何一颗二叉树中,如果其叶子节点的数量为,度为2的子节点数量为,则;
- 具有 n 个节点的完全二叉树的深度为;
【完全二叉树性质】
- 当 i == 1 时,节点i是二叉树的根;若 i > 1 ,则节点的父节点是 i / 2;
- 若 2i ≤ n ,则节点 i 有左子节点,左子节点的编号是 2i;否则,节点无左子节点,并且是叶子节点;
- 若 2i + 1 ≤ n,则节点 i 有右子节点,右子节点编号是 2i + 1;否则,节点无右子节点;
- 1 ~ n/2 范围的节点都是有子节点的非叶子节点,其余的节点全部都是叶子节点。
3、基本操作
- 初始化
- 为指定节点添加指定节点
- 判断二叉树是否为空
- 返回根节点
- 返回指定节点的父节点
- 返回指定节点的左子节点
- 返回指定节点的右子节点
- 返回该二叉树的深度
- 返回指定节点的位置
4、存储方式
(1)顺序存储
顺序存储二叉树的思想就是,将树中不同的节点存入数组的不同位置。
(2)链表存储
【二叉树】
二叉链表存储的思想是,让每个节点都能记住它的左、右子节点。
【三叉树】