1、数组
- 内存地址连续,使用之前必须要指定数组长度
- 可以通过下标访问的方式访问成员
- 增删操作会给系统带来性能消耗来保证数组下标越界的问题,需要动态扩容。
int a[] = new int[]{1,2,3,4,5};
int a[] = new int[5];
a[0] = 1;
2、链表
- 单向链表:每一个链表节点都具有下一个节点的地址
- 双向链表:每一个链表节点都具有上一个节点的地址与下一个节点的地址
- 灵活的空间要求,不需要连续内存
- 不支持下标访问,读写效率降低,支持顺序遍历检索
- 插入只需要对节点的前后地址进行修改即可,无需移动元素,删除增加的效率更高。
3、树
3.1、二叉树
- 某节点的左子树节点仅包含小于该节点的值
- 某节点的右子树节点仅包含大于该节点的值
- 左右子树每个也必须是二叉查找树
- 顺序排列
3.2、红黑树
3.2.1、基本规则
红黑树是一个自平衡的二叉树,树上的节点满足如下规则
- 每个节点是红色或黑色
- 根节点必须是黑色
- 每个叶子结点是黑色(叶子结点都是空节点)
- 每个红色节点的两个子节点必须是黑色,即红色不能相邻
- 任意节点到每个叶子结点的路径包含相同数量的黑色节点。
所以,红黑树是一个黑平衡二叉树。
3.2.2、操作规则
红黑树的三种操作:变色,左旋和右旋
- 左旋:以某个节点作为支点(旋转节点),其右子节点变为旋转节点的父节点,右子节点的左子节点变为旋转节点的右子节点,左子节点保持不变。之所以叫左旋,就是因为旋转节点变为新的父节点的左子节点。
- 右旋:以某个节点作为支点(旋转节点),其左子节点变为旋转节点的父节点,左子节点的右子节点变为旋转节点的左子节点,右子节点保持不变。之所以叫右旋,就是因为旋转节点变为新的父节点的右子节点。
- 变色:节点的颜色由黑变红或红变黑。
3.2.3、发生情景
插入的新节点默认为红色
1、红黑树为空
- 插入一个黑色根节点
2、插入节点的父节点为黑色
- 直接插入
3、插入节点的父节点为红色
3.1、叔叔节点存在且为红色
- 将父节点与叔叔节点设置为黑色
- 将祖父节点设置为红色
- 依照规则进行判断祖父节点是否变为黑色
3.2、叔叔节点不存在或为黑色
父节点是祖父节点的左节点,插入点是父节点的左节点
- 将父节点设置为黑色
- 将祖父节点设置为红色
- 对祖父节点进行右旋
父节点是祖父节点的左节点,插入点是父节点的右节点
- 父节点进行一次左旋
- 父节点变为黑色
- 祖父节点变为红色
- 将祖父节点进行一次右旋
父节点是祖父节点的右节点,插入点是父节点的左节点
- 父节点进行一次右旋
- 将父节点设置为黑色
- 将祖父节点设置为红色
- 将祖父节点进行一次左旋
父节点是祖父节点的右节点,插入点是父节点的右节点
- 将父节点设置为黑色
- 将祖父节点设置为红色
- 对祖父节点进行左旋