🦁
Voyz的算法笔记
  • Voyz的算法笔记
  • 归纳总结
    • 排序算法
    • 二分法
    • 滑动窗口
    • 双指针
    • 动态规划
    • DFS/回溯算法
    • BFS
    • 贪心算法
  • 排序算法
    • 冒泡排序
    • 选择排序
    • 插入排序
    • 希尔排序
    • 归并排序
    • 快速排序
    • 堆排序
    • 计数排序
    • 桶排序
    • 基数排序
  • 数组
    • 数组中第k大的元素
    • 最长上升子数组
    • 构建乘积数组
    • 和为 s 的连续正数序列
    • 和为 s 的两个数字
    • 连续子数组的最大和
    • 排序数组中的出现次数
    • 奇数位于偶数前
    • 数组中超过一半的数字
    • 旋转数组的最小数字
    • 左旋转字符串
    • 合并有序数组
  • 字符串
    • 电话号码的字母组合
    • 判断回文字符串
    • 生成有效括号
    • 找出回文子串
    • 最长公共前缀
    • 翻转单词顺序
    • 替换空格
    • Z字形变换
  • 矩阵
    • 矩阵置零
    • 螺旋矩阵
    • 搜索二维矩阵
    • 旋转图像
    • 杨辉三角
    • 矩阵查找
    • 矩阵中的路径
    • 顺时针打印矩阵
  • 栈和队列
    • 定义栈数据结构
    • 根据身高重建队列
    • 计算后缀表达式
    • 中缀转后缀
    • 包含 min 函数的栈
    • 从尾到头打印链表
    • 队列的最大值
    • 滑动窗口的最大值
    • 用两个栈实现队列
    • 栈的压入、弹出序列
    • 判断括号有效
  • 哈希表
    • 第一个只出现一次的字符
    • 数组中重复的数字
    • LRU 缓存机制
  • 链表
    • 反转链表
    • 反转链表部分链表
    • 复制带随机指针的链表
    • 复制复杂链表
    • 删除倒数第n个节点
    • 合并两个排序的链表
    • 链表倒数第 k 个节点
    • 两个链表的第一个公共节点
    • 删除链表的节点
    • 环形链表入环位置
    • 链表是否有环
    • 判断回文链表
    • K 个一组翻转链表
  • DFS/回溯算法
    • 不重复字母构成字符串
    • 单词搜索
    • 岛屿数量
    • 分割回文串
    • 全排列
    • 数组组合总和
    • 子集
    • 机器人的运动范围
  • BFS
    • 从上到下打印二叉树
    • 从上到下打印二叉树II
    • 从上到下打印二叉树III
    • 二叉树的最小深度
    • 打开转盘锁
  • 动态规划
    • 打家劫舍I
    • 打家劫舍 II
    • 打家劫舍 III
    • 股票问题汇总
    • 零钱兑换
    • 爬楼梯
    • 最大正方形
    • 把数字翻译成字符串
    • 丑数
    • 斐波那契数列
    • 礼物的最大价值
    • 圆圈中最后剩下的数字
    • 添加符号得到目标和方法数
  • 树
    • 【二叉树】翻转
    • 【二叉树】构造by前序中序
    • 【二叉树】构造by中序后序
    • 【二叉树】合并
    • 【二叉树】镜像
    • 【二叉树】判断对称
    • 【二叉树】前中后序遍历
    • 【二叉树】深度
    • 【二叉树】展开为链表
    • 【二叉树】直径
    • 【二叉树】重复的子树
    • 【二叉树】最近公共祖先
    • 【二叉树】B是A的子结构
    • 【二叉搜索树】第K大元素
    • 【二叉搜索树】第K小元素
    • 【二叉搜索树】构造/遍历
    • 【二叉搜索树】判断
    • 【二叉搜索树】判断后序遍历
    • 【二叉搜索树】转累加树
    • 【二叉搜索树】转排序双向链表
    • 【二叉搜索树】最近公共祖先
    • 【红黑树】构造
    • 【路径和】根到叶子节点
    • 【路径和】为某一值的集合
    • 【路径和】最大值
    • 【平衡二叉树】判断
    • 【对称二叉树】判断
    • 【完美二叉树】填充右侧指针
    • 【依赖关系树】打包顺序数组
    • 【最大二叉树】构建
  • 位运算
    • 比特位计数
    • 出现超过一半的数字
    • 汉明距离
    • Pow(x, n)
    • 不用加减乘除做加法
    • 二进制中 1 的个数
    • 两个只出现一次的数字
  • 贪心算法
    • 加油站
    • 剪绳子
    • 跳跃游戏
    • 无重叠区间
    • 用最少数量的箭引爆气球
  • 双指针
    • 接雨水
    • 盛最多水的容器
    • 长度最小的连续子数组
    • n数之和
  • 分治算法
    • 为运算表达式设计优先级
  • 二分法
    • 缺失的数字
    • 旋转数组的最小元素
    • 排序数组中查找左右区间
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 树

【红黑树】构造

红黑树(Red-Black Tree 「RBT」):自平衡(不是绝对的平衡)的二叉查找树(BST)。

  • 规则:

1. 树的根始终是黑色的 (黑土地孕育黑树根)

  1. 2. 没有两个相邻的红色节点(红色节点不能有红色父节点或红色子节点,并没有说不能出现连续的黑色节点)

  2. 3. 从节点(包括根)到其任何后代NULL节点(叶子结点下方挂的两个空节点,并且认为他们是黑色的)的每条路径都具有相同数量的黑色节点

  • 作用:

红黑树是一种自平衡二叉树,查找时算法时间复杂度为O(log n)。

let btins = new RBT();
let ary = [5, 3, 6, 8, 4, 2];


ary.forEach(value => btins.add(value));
btins.generateDepthString1();
// ///////////////
//      5       //
//    /   \     //
//   3     8    //
//  / \   /     //
// 2  4  6      //
// ///////////////
console.log(btins.minmun());  // 2
console.log(btins.maximum()); // 8
const RED = true;
const BLACK = false;
class Node {
    constructor(key, value) {
        this.key = key;
        this.value = value;
        this.left = null;
        this.right = null;
        this.color = RED;
    }
}
class RBT {
    constructor() {
        this.root = null;
        this.size = 0;
    }
    isRed(node) {
        if (!node) return BLACK;
        return node.color;
    }
    // 左旋 右红左黑
    leftRotate(node) {
        let tmp = node.right;
        node.right = tmp.left;
        tmp.left = node;
        tmp.color = node.color;
        node.color = RED;
        return tmp;
    }
    // 右旋转 左红左子红
    rightRoate(node) {
        let tmp = node.left;
        node.left = tmp.right;
        tmp.right = node;
        tmp.color = node.color;
        node.color = RED;
        return tmp;
    }
    // 颜色翻转
    flipColors(node) {
        node.color = RED;
        node.left.color = BLACK;
        node.right.color = BLACK;
    }
    add(key, value) {
        this.root = this.addRoot(this.root, key, value);
        this.root.color = BLACK; // 根节点始终是黑色
    }
    addRoot(node, key, value) {
        if (!node) {
            this.size++;
            return new Node(key, value);
        }
        if (key < node.key) {
            node.left = this.addRoot(node.left, key, value);
        } else if (key > node.key) {
            node.right = this.addRoot(node.right, key, value);
        } else {
            node.value = value;
        }
        if (this.isRed(node.right) && !this.isRed((node.left))) {
            node = this.leftRotate(node);
        }
        if (this.isRed(node.left) && this.isRed((node.left.left))) {
            node = this.rightRoate(node);
        }
        if (this.isRed(node.left) && this.isRed(node.right)) {
            this.flipColors(node);
        }
        return node;
    }
    isEmpty() {
        return this.size == 0 ? true : false;
    }
    getSize() {
        return this.size;
    }
    contains(key) {
        let ans = '';
        !(function getNode(node, key) {
            if (!node || key == node.key) {
                ans = node;
                return node;
            } else if (key > node.key) {
                return getNode(node.right, key);
            } else {
                return getNode(node.right, key);
            }
        })(this.root, key);
        return !!ans;
    }
    // bst前序遍历(递归版本)
    preOrder(node = this.root) {
        if (node == null) return;
        console.log(node.key);
        this.preOrder(node.left);
        this.preOrder(node.right);
    }
    preOrderNR() {
        if (this.root == null) return;
        let stack = [];
        stack.push(this.root);
        while (stack.length > 0) {
            let curNode = stack.pop();
            console.log(curNode.key);
            if (curNode.right != null) stack.push(curNode.right);
            if (curNode.left != null) curNode.push(curNode.left);
        }
    }
    // bst中序遍历
    inOrder(node = this.root) {
        if (node == null) return;
        this.inOrder(node.left);
        console.log(node.key);
        this.inOrder(node.right);
    }
    // bst后续遍历
    postOrder(node = this.root) {
        if (node == null) return;
        this.postOrder(node.left);
        this.postOrder(node.right);
        console.log(node.key);
    }
    // bsf + 队列的方式实现层次遍历
    generateDepthString1() {
        let queue = [];
        queue.unshift(this.root);
        while (queue.length > 0) {
            let tmpqueue = []; let ans = [];
            queue.forEach(item => {
                ans.push(item.key);
                item.left ? tmpqueue.push(item.left) : '';
                item.right ? tmpqueue.push(item.right) : '';
            });
            console.log(...ans);
            queue = tmpqueue;
        }
    }
    minmun(node = this.root) {
        if (node.left == null) return node;
        return this.minmun(node.left);
    }
    maximum(node = this.root) {
        if (node.right == null) return node;
        return this.maximum(node.right);
    }
}
上一页【二叉搜索树】最近公共祖先下一页【路径和】根到叶子节点

最后更新于3年前

这有帮助吗?