二叉查找树

二叉查找树

你。 提交于 2020-12-17 05:22:10
二叉查找树:Binary Search Tree 对于二叉树的任何一个节点K,左子树的任意一个节点都小于K,右子树的任意一个节点都大于或等于K,按照中序周游将各个节点打印出来会得到由小到大的排列。 节点定义的接口 /** ADT for binary tree nodes */ public interface BinNode<E> { /** Get and set the element value */ public E element(); public void setElement(E v); /** @return The left child */ public BinNode<E> left(); /** @return The right child */ public BinNode<E> right(); /** @return True if a leaf node, false otherwise */ public boolean isLeaf(); } 二叉树的节点定义,实现了上述接口 /** * Binary tree node implementation: Pointers to children * * @param E * The data element * @param Key * The associated key for the

Leetcode题解——数据结构之树

戏子无情 提交于 2020-03-21 09:06:04
递归 1. 树的高度 2. 平衡树 3. 两节点的最长路径 4. 翻转树 5. 归并两棵树 6. 判断路径和是否等于一个数 7. 统计路径和等于一个数的路径数量 8. 子树 9. 树的对称 10. 最小路径 11. 统计左叶子节点的和 12. 相同节点值的最大路径长度 13. 间隔遍历 14. 找出二叉树中第二小的节点 层次遍历 1. 一棵树每层节点的平均数 2. 得到左下角的节点 前中后序遍历 1. 非递归实现二叉树的前序遍历 2. 非递归实现二叉树的后序遍历 3. 非递归实现二叉树的中序遍历 BST 1. 修剪二叉查找树 2. 寻找二叉查找树的第 k 个元素 3. 把二叉查找树每个节点的值都加上比它大的节点的值 4. 二叉查找树的最近公共祖先 5. 二叉树的最近公共祖先 6. 从有序数组中构造二叉查找树 7. 根据有序链表构造平衡的二叉查找树 8. 在二叉查找树中寻找两个节点,使它们的和为一个给定值 9. 在二叉查找树中查找两个节点之差的最小绝对值 10. 寻找二叉查找树中出现次数最多的值 Trie 1. 实现一个 Trie 2. 实现一个 Trie,用来求前缀和 递归 一棵树要么是空树,要么有两个指针,每个指针指向一棵树。树是一种递归结构,很多树的问题可以使用递归来处理。 1. 树的高度 104. Maximum Depth of Binary Tree (Easy)

OneBug-二叉查找树搜索区间

坚强是说给别人听的谎言 提交于 2020-03-16 20:34:41
题目 给定两个值 k1 和 k2(k1 < k2)和一个二叉查找树的根节点。找到树中所有值在 k1 到 k2 范围内的节点。即打印所有 x (k1 <= x <= k2) 其中 x 是二叉查找树的中的节点值。返回所有升序的节点值。 样例 1: 输入: 5 k1 = 6, k2 = 10 输出: [] 样例 2: 输入: 20 / 8 22 / 4 12 k1 = 10, k2 = 22 输出: [12,20,22] 代码实现 class Solution { public: /** * @param root: The root of the binary search tree. * @param k1 and k2: range k1 to k2. * @return: Return all keys that k1<=key<=k2 in increasing order. */ vector<int> ans; void dfs(TreeNode* node, int k1, int k2) { if (node->left && node->val>=k1) //首先往左边走找最小的且符合条件的数 dfs(node->left, k1, k2); if (node->val >= k1 && node->val <= k2) //若左子树的都遍历完毕

阶段总结(三)——为什么有了散列表我们还需要二叉树

南笙酒味 提交于 2020-03-04 05:17:40
二叉查找树最大的特点就是,支持动态数据集合的快速插入、删除、查找操作。 散列表也是支持这些操作的,而且散列表的这些操作比二叉查找树更高效,时间复杂度是 O(1)。 既然散列表如此高效,那么散列表是不是可以完全替代二叉树呢。 或者说有没有什么地方用散列表是做不了的,必须用二叉树呢? 散列表的插入、删除、查找操作的时间复杂度可以做到常量级的 O(1),非常高效。 而二叉查找树在比较平衡的情况下,插入、删除、查找操作时间复杂度才是 O(logn)。 但是为什么我们不能完全用散列表去替代二叉树呢? 一 散列表中的数据是无序存储的,如果要输出有序的数据,需要先进行排序。 而对于二叉查找树来说,我们只需要中序遍历,就可以在 O(n) 的时间复杂度内,输出有序的数据序列。 二 散列表扩容耗时很多,而且当遇到散列冲突时,性能不稳定。 尽管二叉查找树的性能也不稳定,但是在工程中,最常用的平衡二叉查找树的性能非常稳定,时间复杂度稳定在 O(logn)。 三 尽管散列表的查找等操作的时间复杂度是常量级的,但因为哈希冲突的存在,这个常量不一定比 logn 小,所以实际的查找速度可能不一定比 O(logn) 快。加上哈希函数的耗时,也不一定就比平衡二叉查找树的效率高。 四 散列表的构造比二叉查找树要复杂,需要考虑的东西很多。比如散列函数的设计、冲突解决办法、扩容、缩容等。

二叉查找树与平衡二叉树

£可爱£侵袭症+ 提交于 2020-02-26 01:28:19
最近在看一些底层东西,涉及到一些树型结构的数据算法,找到一篇非常不错的文章,先膜拜然后在copy过来。 其中可能涉及一些概念,比如:中序遍历,高度什么的,在发个链接参考: https://www.jianshu.com/p/d1133ef8bc0e 二叉查找树   二叉查找树,也称二叉搜索树,或二叉排序树。其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树: (1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2) 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3) 任意节点的左、右子树也分别为二叉查找树; (4) 没有键值相等的节点。   如上图所示,是不同形态的二叉查找树。二叉查找树是对要查找的数据进行生成树,左支的值小于右支的值。在查找的时候也是一样的思路,从根节点开始,比节点大进入右支,比节点小进入左支,直到查找到目标值。   二叉查找树的插入算法比较简单:空树,就首先生成根节点;不是空树就按照查找的算法,找到父节点,然后作为叶子节点插入,如果值已经存在就插入失败。   删除操作稍微复杂一点,有如下几种情况: ​ (1)如果删除的是叶节点,可以直接删除; ​ (2)如果被删除的元素有一个子节点,可以将子节点直接移到被删除元素的位置; ​ (3)如果有两个子节点,这时候就采用中序遍历,找到待删除的节点的后继节点

(略难)二叉查找树的删除

泄露秘密 提交于 2020-02-21 18:43:25
这是一道想起来简单,但是实现起来困难的题目,因为要考虑的情况有点多 https://www.lintcode.com/problem/remove-node-in-binary-search-tree/ 1.删除节点是叶节点,直接删除 2.删除节点是非叶节点,且非满节点,可用其子树节点取代 3.删除节点是满节点 首先找到其后续节点(中序遍历下一个,即其右子树的最左节点) 3.1如果后续节点和删除节点是相邻两层,即后续节点是删除节点的右子树。则直接将后续节点赋值给删除节点,记得相关父子节点关系理清,(删除节点的左子树等) 3.2如果后续节点和删除节点不在相邻层,这个情况下直接更改删除节点中的value,然后理清后续节点的子树关系,虽然后续节点是最左节点,但他也有可能有右子树。这个时候需要将后续节点的子树赋值给其父节点。 注意要点: 1.在写程序时,开头就要有一个意识,就是时刻保存三个值,父节点,现节点,和子树。 2.判断是否为3.1情况的条件为 tmp->right->left==NULL ,如果不是再开始进行while循环找到最左节点。 class Solution { public: /** * @param root: The root of the binary search tree. * @param value: Remove the node with given

数据结构--二叉搜索树2

浪尽此生 提交于 2020-02-06 16:45:50
之前我们实现了简单的二叉搜索树,现在介绍一下,STL中的容器,应对需要使用二叉搜索树的情况其实,大多数时候,用STL中的set就够了,不需要自己实现 1 #include <iostream> 2 #include <cstdio> 3 #include <set> 4 5 using namespace std; 6 7 // set的内部结构其实不只是搜索二叉树那么简单 8 // set是一种自平衡二叉查找树,名叫红黑树 9 // 如果要对复杂的数据进行操作,需要重写仿函数,来进行大小的确定 10 11 int main() 12 { 13 set<int> s; 14 15 s.insert(1); 16 s.insert(3); 17 s.insert(6); 18 s.insert(5); 19 20 set<int>::iterator it; 21 22 it=s.find(3); 23 24 if(it==s.end()) 25 { 26 puts("find error\n"); 27 } 28 else 29 { 30 puts("find it\n"); 31 } 32 33 s.erase(3); 34 35 it=s.find(3); 36 37 if(it==s.end()) 38 { 39 puts("find error\n"); 40 } 41

红黑树算法原理

拜拜、爱过 提交于 2020-02-01 15:58:53
原文: 红黑树深入剖析及Java实现 ,本文修改了原文的一些小错误,如果想看红黑树的Java实现可以到原文去看。 红黑树是平衡二叉查找树的一种 。为了深入理解红黑树,我们需要从二叉查找树开始讲起。 BST 二叉查找树(Binary Search Tree,简称BST)是一棵二叉树,它的左子节点的值比父节点的值要小,右节点的值要比父节点的值大。 它的高度决定了它的查找效率。 在理想的情况下,二叉查找树增删查改的时间复杂度为O(logN)(其中N为节点数),最坏的情况下为O(N)。当它的高度为logN+1时,我们就说二叉查找树是平衡的。 BST的查找操作 T key = a search key Node root = point to the root of a BST while ( true ){ if (root== null ){ break ; } if (root.value.equals(key)){ return root; } else if (key.compareTo(root.value)< 0 ){ root = root.left; } else { root = root.right; } } return null ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 从程序中可以看出,当BST查找的时候

查找、插入、删除都很快的数据结构(散列表vs红黑树vs跳表)

左心房为你撑大大i 提交于 2020-01-31 04:18:09
散列表 散列表的插入、删除、查找操作的时间复杂度可以做到常量级的 O(1),非常高效。 平衡二叉查找树(红黑树) 二叉查找树在比较平衡的情况下(红黑树是一种平衡二叉树),插入、删除、查找操作时间复杂度是 O(logn)。 跳表 跳表,插入、删除、查找操作时间复杂度是 O(logn)。 散列表 vs 二叉查找树 相对散列表,二叉查找树好像并没有什么优势,那我们为什么还要用二叉查找树呢? 第一, 散列表中的数据是无序存储的 ,如果要输出有序的数据,需要先进行排序。而对于二叉查找树来说,我们只需要中序遍历,就可以在 O(n) 的时间复杂度内,输出有序的数据序列。 第二,散列表扩容耗时很多,而且当 遇到散列冲突时,性能不稳定 ,尽管二叉查找树的性能不稳定,但是在工程中,我们最常用的平衡二叉查找树的性能非常稳定,时间复杂度稳定在 O(logn)。 比如:红黑树的插入、删除、查找各种操作性能都比较稳定。对于工程应用来说,要面对各种异常情况,为了支撑这种工业级的应用,我们更倾向于这种性能稳定的平衡二叉查找树 第三,笼统地来说,尽管散列表的查找等操作的时间复杂度是常量级的,但 因为哈希冲突的存在,这个常量不一定比 logn 小 ,所以实际的查找速度可能不一定比 O(logn) 快。加上哈希函数的耗时,也不一定就比平衡二叉查找树的效率高。 第四, 散列表的构造比二叉查找树要复杂 ,需要考虑的东西很多

二叉查找(排序)树

此生再无相见时 提交于 2020-01-29 01:57:35
package four_tree . binarySearchTree ; /** * Author:jinpma * Date :2019/12/22 */ public class BinarySearchTree { public static void main ( String [ ] args ) { int array [ ] = { 7 , 3 , 10 , 12 , 5 , 1 , 9 , 2 } ; BinaryTreeDemo bt = new BinaryTreeDemo ( ) ; for ( int i = 0 ; i < array . length ; i ++ ) { bt . add ( new Node ( array [ i ] ) ) ; } bt . inOrder ( ) ; } static class BinaryTreeDemo { public Node root ; public void setter ( Node root ) { this . root = root ; } public void inOrder ( ) { if ( this . root == null ) { System . out . println ( "空树" ) ; } else { this . root . inOrder ( )