一、定义
二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
二、分类

参考资料:
一句话弄懂常见二叉树类型
wiki Binary tree
满二叉树
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树
完全二叉树
一棵二叉树至多只有最下面的一层上的结点的度数可以小于2,并且最下层上的结点都集中在该层最左边的若干位置上,则此二叉树成为完全二叉树。
平衡二叉树
它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
二叉搜索树
它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
红黑树
平衡二叉搜索树
三、最小堆|最大堆
参考资料:
https://zhuanlan.zhihu.com/p/37968599
https://www.zhihu.com/question/36134980/answer/87490177
https://en.wikipedia.org/wiki/Binary_heap
定义
堆是一类特殊的树,堆的通用特点就是父节点会大于或小于所有子节点
下,堆并不一定是完全二叉树,平时使用完全二叉树的原因是易于存储,并且便于索引。
最小堆特点
- k=父节点的index -> 左子节点的index = 2k + 1, 右子节点的index = (k + 1) x 2【完全二叉树特性】
- j = 子节点的index -> 父节点的index = (j -1) / 2【完全二叉树特性】
- 根元素是最小的元素,父节点小于它的两个子节点。
- 可以完美的放入数组中。如图下图
image.png
注意:最小堆用户排序时,保证的是根节点为最小,故我们每次取值时,都是获取根节点,而后树会进行一个下沉过程重排序
使用场景
PriorityQueue
技术实现
上浮和下沉
源码实现
/**
* /最小堆
**/
static class MinHeap {
//定义数组,存储对象
private Integer[] queue;
//堆当前大小
private int size;
public MinHeap(Integer[] data, int arrSize) {
queue = data;
size = arrSize;
heapify();
}
//添加数据
public boolean offer(int value) {
queue[++size] = value;
siftUp(size - 1, value);
return true;
}
//获取数据
public Integer take() {
if (size == 0) {
return null;
}
int returnValue = queue[0];
queue[0] = queue[size - 1];
queue[size - 1] = null;
size--;
if (size != 0) {
siftDown(0, queue[0]);
}
return returnValue;
}
//下沉核心方法
private void siftDown(int i, int value) {
//求半数
int half = size >>> 1;
while (i < half) {
int child = (i << 1) + 1;
int c = queue[child];
int right = child + 1;
if (right < size && c > queue[right]) {
c = queue[child = right];
}
if (value < c) {
break;
}
queue[i] = c;
i = child;
}
queue[i] = value;
}
//上浮核心方法
private void siftUp(int i, int value) {
while (i > 0) {
int parent = (i - 1) >> 2;
int p = queue[parent];
if (value > p) {
break;
}
queue[i] = p;
i = parent;
}
queue[i] = value;
}
//内部排序
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--) {
siftDown(i, queue[i]);
}
}
}
网友评论