二叉搜索树

图解红黑树

社会主义新天地 提交于 2020-03-10 20:58:14
图解红黑树 一、红黑树的五条规则 红黑树除了符合二叉搜索树的基本规则外,还添加了以下特性: 规则1:节点是红色或黑色的; 规则2:根节点是黑色的; 规则3:每个叶子节点都是黑色的空节点(NIL节点); 规则4:每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不可能有两个连续的红色节点); 规则5:从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点; 红黑树的相对平衡 前面5条规则的约束确保了以下红黑树的关键特性: 从 根到叶子节点 的 最长路径 ,不会超过 最短路径 的 两倍 ; 结果就是这棵树 基本 是平衡的; 虽然没有做到绝对的平衡,但是可以保证在最坏的情况下,该树依然是高效的; 为什么可以做到 最长路径不超过最短路径的两倍 呢? 性质4 决定了路径上不能有两个相连的红色节点; 所以,最长路径一定是红色节点和黑色节点交替而成的; 由于根节点和叶子节点都是黑色的,最短路径可能都是黑色节点,并且最长路径中一定是黑色节点多于红色节点; 性质5 决定了所有路径上都有相同数目的黑色节点; 这就表明了没有路径能多于其他任何路径两倍长。 二、红黑树的三种变换 插入一个新节点时,有可能树不再平衡,可以通过三种方式的变换使树保持平衡: 变色 ; 左旋转 ; 右旋转 ; 2.1.变色 为了重新符合红黑树的规则,需要把 红色 节点变为 黑色 ,或者把 黑色 节点变为 红色 ;

力扣5339 二叉搜索子树的最大键值和 解题报告

雨燕双飞 提交于 2020-03-10 10:22:13
目录 题目描述 思路分析 ac代码 题目描述 链接: https://leetcode-cn.com/problems/maximum-sum-bst-in-binary-tree/ 给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。 二叉搜索树的定义如下: 任意节点的左子树中的键值都 小于 此节点的键值。 任意节点的右子树中的键值都 大于 此节点的键值。 任意节点的左子树和右子树都是二叉搜索树。 示例 1: 输入:root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6] 输出:20 解释:键值为 3 的子树是和最大的二叉搜索树。 示例 2: 输入:root = [4,3,null,1,2] 输出:2 解释:键值为 2 的单节点子树是和最大的二叉搜索树。 示例 3: 输入:root = [-4,-2,-5] 输出:0 解释:所有节点键值都为负数,和最大的二叉搜索树为空。 示例 4: 输入:root = [2,1,3] 输出:6 示例 5: 输入:root = [5,4,8,3,null,6,3] 输出:7 提示: 每棵树最多有 40000 个节点。 每个节点的键值在 [-4 * 10^4 , 4 * 10^4] 之间。 来源:力扣(LeetCode) 链接:https://leetcode-cn

JavaScript实现树结构(一)

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-09 08:52:08
JavaScript实现树结构(一) 一、树结构简介 1.1.简单了解树结构 什么是树? 真实的树: 树的特点: 树一般都有一个 根 ,连接着根的是 树干 ; 树干会发生分叉,形成许多 树枝 ,树枝会继续分化成更小的 树枝 ; 树枝的最后是 叶子 ; 现实生活中很多结构都是树的抽象,模拟的树结构相当于旋转 180° 的树。 树结构对比于数组/链表/哈希表有哪些优势呢: 数组: 优点:可以通过 下标值访问 ,效率高; 缺点:查找数据时需要先对数据进行 排序 ,生成 有序数组 ,才能提高查找效率;并且在插入和删除元素时,需要大量的 位移操作 ; 链表: 优点:数据的插入和删除操作效率都很高; 缺点: 查找 效率低,需要从头开始依次查找,直到找到目标数据为止;当需要在链表中间位置插入或删除数据时,插入或删除的效率都不高。 哈希表: 优点:哈希表的插入/查询/删除效率都非常高; 缺点: 空间利用率不高 ,底层使用的数组中很多单元没有被利用;并且哈希表中的元素是 无序 的,不能按照固定顺序遍历哈希表中的元素;而且不能快速找出哈希表中 最大值或最小值 这些特殊值。 树结构: 优点:树结构综合了上述三种结构的优点,同时也弥补了它们存在的缺点(虽然效率不一定都比它们高),比如树结构中数据都是有序的,查找效率高;空间利用率高;并且可以快速获取最大值和最小值等。 总的来说:

二叉搜索树 | 验证二叉搜索树

馋奶兔 提交于 2020-03-09 08:49:33
文章目录 问题:验证二叉搜索树 解题思路 C++代码 问题:验证二叉搜索树 问题链接 解题思路 由于BST是递归定义的数据结构,因此我们采用递归的思路进行判断。 空树和只有一个节点的树可以视为BST root有左子树,判断左子树是否为BST,如果左子树是BST接着判断其最大的值是否小于root的值 root有右子树,判断右子树是否为BST,如果右子树是BST接着判断其最小的值是否大于root的值 C++代码 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public : bool isValidBST ( TreeNode * root ) { if ( ! root ) return true ; if ( ! root - > left && ! root - > right ) return true ; //一个节点 bool flag = true ; //如果有左子树,则左子树也应该是二叉搜索树,且其最大的节点值小于root的节点值 if (

题目:给定一个二叉搜索树(BST),找到树中第 K 小的节点。

跟風遠走 提交于 2020-03-08 19:59:14
题目:给定一个二叉搜索树(BST),找到树中第 K 小的节点。 出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家 参考答案: 考察点 基础数据结构的理解和编码能力 递归使用 示例 ``` 说明:保证输入的 K 满足 1<=K<=(节点数目) 树相关的题目,第一眼就想到递归求解,左右子树分别遍历。联想到二叉搜索树的性质,root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1,那么 root 就是结果,否则如果左子树节点数目小于 K-1,那么结果必然在右子树,否则就在左子树。因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。 ``` /** * Definition for a binary tree node. **/ public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } class Solution { private class ResultType { boolean found; // 是否找到 int val; // 节点数目 ResultType(boolean found, int val) { this.found = found; this.val = val; } } public int

【数据结构】AVL树代码(Java版)

我是研究僧i 提交于 2020-03-08 14:57:52
AVL树 AVL树 BinaryTree.java BST.java AVLTree.java AVL树是在二叉搜索树的基础上学习的, 【数据结构】二叉搜索树 AVL树 AVL 树是晶早发明的自平衡二叉搜索树之— 平衡因子 (Balance Factor):某结点的左右子树的高度差 AVL树的特点 每个节点的平衡因子只可能是1、0、-1 (绝对值≤1,如果超过1,称之为“失衡") 每个节点的左右子树高度差不超过1 搜索、添加、删除 的时间复杂度是 o ( l o g n ) o(logn) o ( l o g n ) BinaryTree.java 在二叉搜索树的 BinaryTree.java 的基础上增加了 createNode() 方法,原因是 AVL树 拥有自己的节点(增加了height属性)。 /** * 二叉树 */ @SuppressWarnings ( "unchecked" ) public class BinaryTree < E > { protected int size ; // 元素数量 protected Node < E > root ; // 根节点 /** * 访问器接口 ——> 访问器抽象类 * 增强遍历接口 */ public static abstract class Visitor < E > { boolean stop ; //

二叉搜索树迭代器(栈)

ε祈祈猫儿з 提交于 2020-03-08 06:19:14
题目: https://leetcode-cn.com/problems/binary-search-tree-iterator/ /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class BSTIterator { public : /* *实现一个二叉搜索树迭代器。你将使用二叉搜索树的 *根节点初始化迭代器。调用 next() 将返回二叉搜索 *树中的下一个最小的数。 */ stack < TreeNode * > st ; BSTIterator ( TreeNode * root ) { while ( root ) { st . push ( root ) ; root = root - > left ; } } int next ( ) { TreeNode * p = st . top ( ) ; st . pop ( ) ; int ans = p - > val ; p = p - > right ; while ( p ) { st . push ( p ) ; p =

将有序数组转换成二叉搜索树​​​​​​​(python)

纵饮孤独 提交于 2020-03-06 05:09:19
LeetCode: 108 将有序数组转换成二叉搜索树 将一个按照 升序排列的有序数组 转换为一棵高度 平衡二叉搜索树 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 示例: 给定有序数组: [-10,-3,0,5,9], 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 0 / \ -3 9 / / -10 5 思路: 递归,每次都取有序数组的中值==root, 左侧为左子树递归+右侧为右子树递归 定义二叉树: # Definition for a binary tree node. class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None 代码实现: from typing import List class Solution: def sortedArrayToBST(self, nums: List[int]) -> TreeNode: length=len(nums) if length==0: return None if length==1: return TreeNode(nums[0]) else: root=TreeNode(nums[length//2]

原生JS实现二叉搜索树(Binary Search Tree)

久未见 提交于 2020-03-05 09:53:30
1.简述 二叉搜索树树(Binary Search Tree) ,它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 2.代码说明 首先先创建一个辅助节点类Node,它初始化了三个属性:节点值,左孩子,有孩子。 class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } 接着创建一个二叉搜索树类BST,它初始化了根节点为null。 class BST { constructor() { this.root = null; } } 然后,给这个BST类声明一些方法: insert(value):向树中插入一个节点值为value的节点。 midOrderTraverse(callback):中序遍历树,并将树中的每个节点传入callback回调函数里。 preOrderTraverse(callback):前序遍历树,并将树中的每个节点传入callback回调函数里。 lastOrderTraverse(callback):后序遍历树,并将树中的每个节点传入callback回调函数里。

LeetCode——98. 验证二叉搜索树

懵懂的女人 提交于 2020-03-03 11:38:40
给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 示例 1: 输入: 2 / \ 1 3 输出: true 示例 2: 输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。 递归 利用其本身性质来做,初始化时带入系统最大值和最小值,在递归过程中换成它们自己的节点值,用long代替int就是为了包括int的边界条件,代码如下: C++ class Solution { public: bool isValidBST(TreeNode* root) { return isValidBST(root, LONG_MIN, LONG_MAX); } bool isValidBST(TreeNode* root, long mn, long mx) { if (!root) return true; if (root->val <= mn || root->val >= mx) return false; return isValidBST(root->left, mn, root->val) &&