二叉树

作者: 北海北_6dc3 | 来源:发表于2019-12-26 11:29 被阅读0次

    一、定义

    二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(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]);
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:二叉树

          本文链接:https://www.haomeiwen.com/subject/ovmhoctx.html