【ArrayList和HashMap源码讲解】

ArrayList和HashMap源码讲解

    • 树的常用术语
    • 二叉树
    • 满二叉树
    • 完全二叉树
    • 二叉搜索树(BST)
    • 平衡二叉树
      • 右旋
      • 左旋
      • 左右旋口诀口诀
    • 2-3树
    • 红黑树
    • 红黑树和二叉树的等价性
    • BST(二叉查找树),AVL(平衡二叉树),RBT(红黑树)三种树的应用场景
  • ArrayList和HashMap
    • ArrayList
    • HashMap

树的常用术语

节点:
根节点:
父节点:
子节点:
叶子节点:
节点的权:
度:
路径:
层:
子树:
树的高度:
森林:

二叉树

每个节点最多只能有两个子节点的一种形式的树称为二叉树
二叉树的子节点分为左节点和右节点

满二叉树

所有非叶子节点都存在左子树和右子树,并且所有叶子都在最后一层的二叉树为满二叉树
叶子节点只能在最后一层
非叶子节点的度一定是2
同样深度的二叉树中,满二叉树的节点个数最多,叶子树最多

完全二叉树

1 如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树
2 如果节点的度是1,则该节点只有左孩子
3 同样节点数目的二叉树,完全二叉树深度最小

二叉搜索树(BST)

二叉搜索树也叫做二叉排序树,任何一个非叶子节点,要求左叶子节点的值比当前节点的值小,右子节点的值比当前节点的值大
如果有相同的值,可以将该节点放在左子树或右子节点

二叉搜索树的深度优先遍历
二叉树的深度遍历分为:前序遍历,中序遍历,后序遍历
前序遍历:先输出父节点,再遍历左子树和右子树
中序遍历:先遍历左子树,在输出父节点,再遍历右子树,中序遍历的结果是有序的
后序遍历:先遍历左子树,再遍历右子树,最后输出父节点

练习题:
数据(7,3,10,5,1,9,12),对应的二叉排序树创建过程(深度优先遍历和广度优先遍历)

二叉树的问题(数据1,2,3,4,5,6)
【ArrayList和HashMap源码讲解】_第1张图片
解决方法-平衡二叉树

平衡二叉树

1 平衡二叉树也叫平衡二叉搜索树,需要满足BST的特性
2 任意一个节点。平衡因子的绝对值不超过1
某节点的高度值=max(左子树高度,右子树高度)+1
每个节点的左子树和右子树的高度差叫做平衡因子

如何维持二叉树平衡?

右旋

1 新插入节点导致了不平衡
2 不平衡节点在插入的路径上
3 叶子节点在不平衡节点的左侧的左侧
4 可以使用右旋来实现
R.right = N
N.left=T3 
R =root 

【ArrayList和HashMap源码讲解】_第2张图片

左旋

1 新插入节点导致了不平衡
2 不平衡节点在插入的路径上
3 叶子节点在不平衡节点的右侧的右侧
4 可以使用左旋来实现

叶子节点在不平衡节点的左侧的右侧
先左旋再右旋

叶子节点在不平衡节点的右侧的左侧
先右旋再左旋

左右旋口诀口诀

左旋:自己变成右孩子的左孩子
右旋:自己变成左孩子的右孩子

2-3树

每个节点都可以存放一个元素或者两个元素
存放一个元素的节点称为2-节点,存放两个元素的节点叫做3-节点
每个节点有两个或者三个子节点的树称为2-3树,2-3树满足二叉搜索树的基本性质
2-3树是一个绝对平衡的树

2-3树添加节点遵循三个大的前提:
满足二叉搜索树的特征
维持绝对平衡
不能往null节点插入数据

图例:
【ArrayList和HashMap源码讲解】_第3张图片

红黑树

红黑树定义:
前提:研究红黑树叶子节点指的是最后的空节点(我们原来理解的叶子节点的孩子节点)
红黑树的每个节点都是有颜色的,或是红色或者是黑色
根节点是黑色的
每个叶子节点都是黑色的(红色节点向左倾斜叫做左倾红黑树)
如果一个节点是红色的,那么他的孩子节点都是黑色的
从任何一个节点到叶子节点,经过的黑色节点是一样的

红黑树和二叉树的等价性

【ArrayList和HashMap源码讲解】_第4张图片

BST(二叉查找树),AVL(平衡二叉树),RBT(红黑树)三种树的应用场景

对于完全随机的数据,BST(二叉查找树)不会出现一侧偏斜的情况,极端情况下会退化成链表或者非常不平衡树
对于查询较多的业务场景,AVL(平衡二叉树)是最佳的选择。
RBT(红黑树)的综合性能更优

ArrayList和HashMap

ArrayList

arrayList:延迟加载,在add()的时候初始化。初始容量大小为10,扩容 = 扩容前容量+右移动一位
arraylist不是线程安全的集合,fail-fast 机制保证容错

链表的特征:
链表(Linked list)是一种真正的动态的数据结构
链表是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针
使用链表结构可以克服数组需要预先知道数据大小的缺点,但增加了结点的指针域,空间开销比较大
链表允许插入和移除链表上任意位置上的节点,但是不允许随机存取。
链表有很多中不同的类型:单向链表,双向链表以及循环链表

单链表向头部插入元素:
node.next = head;
head = node;

单链表向中间插入元素:
 node.next = prev.next;
 prev.next =node;
 (注意:计算prev位置,注意索引为0的情况)

HashMap

HashMap在Java8后引入了红黑树,TreeMap,TreeSet的底层也是红黑树。

自己设计hashmap思路
【ArrayList和HashMap源码讲解】_第5张图片

你可能感兴趣的:(java,链表,数据结构)