二叉树

一、定义

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

二、分类

image.png

参考资料:
一句话弄懂常见二叉树类型
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]);
            }
        }
    }

你可能感兴趣的:(二叉树)