二叉查找树

模拟平衡二叉查找树底层实现(AVL)

匿名 (未验证) 提交于 2019-12-03 00:29:01
GitHub源码地址:(https://github.com/BradenLei/AVL) 1、基本概念及操作: 1)平衡二叉查找树:在二叉查找树的基础上满足平衡因子为-1,0,1的树结构 2)平衡因子:右子树的高度减去左子树的高度;-1表示左偏重,+1表示右偏重 3)重新平衡数:从AVL树中插入或者删除一个元素后,如果树变得不平衡了,执行一次旋转操作来重新平衡该树,有四种方式: LL旋转、RR旋转、LR旋转、RL旋转 以 LL说明:两个L表示两次左偏重 4)AVL树的设计:由于AVL树是二叉查找树,AVLTree设计为BST的子类(BST实现在上一篇博文中,这里不再累述) 5)重写insert、delete方法:AVL树中的这两操作基本一致,不同之处在于树可能需要重新平衡。 6)AVL树的高度为O(logn),所以其search、insert以及delete方法的时间复杂度为O(logn) AVL实现: package binary; import java.util.ArrayList; public class AVLTree<E extends Comparable<E>> extends BST<E> { public AVLTree() { } public AVLTree(E[] objects) { super(objects); } @Override

最优二叉查找树_动态规划

匿名 (未验证) 提交于 2019-12-02 23:03:14
原问题是给出各个节点和各个节点的被查找概率,然后构造一棵各个节点平均被查找比较次数最小的树,则该问题可以用动态规划来解决 示例如下 推广到一般的情况,并设T(i, j)是由记录{ri, …, rj}(1≤i≤j≤n)构成的二叉查找树,C(i, j)是这棵二叉查找树的平均比较次数,有下列分析 观察这个表,可知可知左边的表的第一行的第四列就是我们要求的最优平均比较次数,而右边的表我们可以知道在c(i ,j)得到最优解,即平均查找次数最小的根节点,比如一共四个节点,则我们从右边的R(1,4)的值即3是这四个节点构成的树的根节点。则树的左子树变为c(1,2),他的根节点是r(1,2)=2,然后2又有左节点1,而4则是3的根节点。则树的样子便出来了。 代码如下 1 #include<bits/stdc++.h> 2 using namespace std; 3 double BST(int n,double p[],double c[][100],int r[][100]) 4 { 5 for(int i=1;i<=n;i++){//按式1和式2初始化 6 c[i][i-1]=0; 7 c[i][i]=p[i]; 8 r[i][i]=i; 9 } 10 c[n+1][n]=0; 11 for(int d=1;d<n;d++){//安对角线计算,此时是n-1个对角线 12 for(int i

python_二叉查找树 堆排序 优先级队列

匿名 (未验证) 提交于 2019-12-02 22:11:45
Task5 【二叉树】 实现一个二叉查找树,并且支持插入、删除、查找操作 实现查找二叉查找树中某个节点的后继、前驱节点 实现二叉树前、中、后序以及按层遍历 【堆】 实现一个小顶堆、大顶堆、优先级队列 实现堆排序 利用优先级队列合并 K 个有序数组 求一组动态数据集合的最大 Top K 二叉查找树(内部函数已实现BFS与三种DFS算法): class Node ( object ) : def __init__ ( self , value ) : self . value = value self . lchild = None self . rchild = None class BinarySearchTree ( object ) : def __init__ ( self , value ) : self . root = Node ( value ) def find ( self , value , node , parent , nodetype ) : if node is None : return False , node , parent , nodetype elif node . value == value : return True , node , parent , nodetype elif node . value < value :

11. 二叉查找树中搜索区间

送分小仙女□ 提交于 2019-12-02 15:10:49
11. 二叉查找树中搜索区间 给定一个二叉查找树和范围[k1, k2]。按照升序返回给定范围内的节点值。 样例 样例 1: 输入:{5},6,10 输出:[] 5 它将被序列化为 {5} 没有数字介于6和10之间 样例 2: 输入:{20,8,22,4,12},10,22 输出:[12,20,22] 解释: 20 / \ 8 22 / \ 4 12 它将被序列化为 {20,8,22,4,12} [12,20,22]介于10和22之间 /** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: param root: The root of the binary search tree * @param k1: An integer * @param k2: An integer * @return: return: Return all keys that k1<=key

与世无争的帅哥 提交于 2019-12-02 11:42:39
树的介绍 1. 树的定义 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。 把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: (01) 每个节点有零个或多个子节点; (02) 没有父节点的节点称为根节点; (03) 每一个非根节点有且只有一个父节点; (04) 除了根节点外,每个子节点可以分为多个不相交的子树。 2. 树的基本术语 若一个结点有子树,那么该结点称为子树根的"双亲",子树的根是该结点的"孩子"。有相同双亲的结点互为"兄弟"。一个结点的所有子树上的任何结点都是该结点的后裔。从根结点到某个结点的路径上的所有结点都是该结点的祖先。 结点的度 :结点拥有的子树的数目。 叶子 :度为零的结点。 分支结点 :度不为零的结点。 树的度 :树中结点的最大的度。 层次 :根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1。 树的高度 :树中结点的最大层次。 无序树 :如果树中结点的各子树之间的次序是不重要的,可以交换位置。 有序树 :如果树中结点的各子树之间的次序是重要的, 不可以交换位置。 森林 :0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林。 二叉树的介绍 1. 二叉树的定义 二叉树是每个节点最多有两个子树的树结构。它有五种基本形态:二叉树可以是空集

Luogu P1864 [NOI2009]二叉查找树

≡放荡痞女 提交于 2019-12-02 03:24:50
题目 \(v\) 表示权值, \(F\) 表示频率。 首先我们显然可以把这个权值离散化。 然后我们想一下,这个东西它是一棵树对吧,但是我们改变权值会引起其树形态的改变,这样很不好做,所以我们考虑把它转化为序列上的问题。 我们知道这是一个treap对吧,所以它的中序遍历的数据值是递增的,我们考虑这个性质入手,把所有点按数据值从小到大排序,那么连续一段点在树上显然是一个连通块。 设 \(f_{i,j,o}\) 表示只考虑 \([i,j]\) 的点,在所有权值 \(\ge o\) 的情况下的最小答案。那么我们就可以枚举权值和区间,再枚举这个区间的点构成的树的根进行转移了。 设枚举的根为 \(k\) ,那么我们需要满足区间内其它点的权值都比它大。 转移分为两种: \(1.(v_k\ge o):f_{i,j,o}=\min(f_{i,j,o},f_{i,k-1,v_k}+f_{k+1,j,v_k}+\sum\limits_{p=i}^j F_p)\) \(2.f_{i,j,o}=\min(f_{i,j,o},f_{i,k-1,o}+f_{k+1,j,o}+\sum\limits_{p=i}^j F_p+K)\) #include<bits/stdc++.h> using namespace std; const int N=73; struct node{int x,v,f;}a[N];

[洛谷P1864] NOI2009 二叉查找树

跟風遠走 提交于 2019-12-01 20:32:34
问题描述 已知一棵特殊的二叉查找树。根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小。 另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小。 已知树中所有结点的数据值各不相同;所有结点的权值也各不相同。这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定。因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的、按照数据值排序的二叉查找树。 一个结点在树中的深度定义为它到树根的距离加1。因此树的根结点的深度为1。 每个结点除了数据值和权值以外,还有一个访问频度。我们定义一个结点在树中的访问代价为它的访问频度乘以它在树中的深度。整棵树的访问代价定义为所有结点在树中的访问代价之和。 现在给定每个结点的数据值、权值和访问频度,你可以根据需要修改某些结点的权值,但每次修改你会付出K的额外修改代价。你可以把结点的权值改为任何实数,但是修改后所有结点的权值必须仍保持互不相同。现在你要解决的问题是,整棵树的访问代价与额外修改代价的和最小是多少? 输入格式 输入文件中的第一行为两个正整数N,K。其中:N表示结点的个数,K表示每次修改所需的额外修改代价。 接下来的一行为N个非负整数,表示每个结点的数据值。 再接下来的一行为N个非负整数,表示每个结点的权值。

【模板】判断二叉查找树

一世执手 提交于 2019-12-01 07:21:20
二叉查找树其实! 就是平衡树啦 const int N=1e6+10; int n,m; struct node{ int val,lson,rson; }a[N]; inline bool is_bst(int root,int l_bound,int u_bound){ if(root==0)return 1; int cur=a[root].val; return (l_bound <cur) && (cur < u_bound) && is_bst(a[root].lson,l_bound,cur) && is_bst(a[root].rson,cur,u_bound); //值域严格小于/大于 } int main(){ rd(n); rep(i,1,n){ rd(a[i].val),rd(a[i].lson),rd(a[i].rson); } cout<<is_bst(1,INT_MIN,INT_MAX); return 0; } //严格小于/大于 /* 5 6 4 5 5 0 0 3 0 0 4 3 2 7 0 0 */ //1 //可以等于 /* 5 6 4 5 5 0 0 3 0 0 5 3 2 7 0 0 */ //1 来源: https://www.cnblogs.com/sjsjsj-minus-Si/p/11668145.html

用Java实现二叉查找树

回眸只為那壹抹淺笑 提交于 2019-11-30 19:46:13
二叉查找树的实现 1. 原理    二叉查找树,又称为二叉排序树、二叉搜索树。对于树中每一个节点X,它的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。二叉查找树的平均深度为O(log N),搜索元素的时间复杂度也是O(log N)。是两种库集合类TreeSet、TreeMap实现的基础。 2. public API void makeEmpty( ) --> 置空boolean isEmpty( ) --> 判空AnyType findMin( ) --> 寻找最小值AnyType findMax( ) --> 寻找最大值boolean contains( x ) --> 是否存在元素xvoid insert( x ) --> 插入元素xvoid remove( x ) --> 删除元素xvoid printTree( ) --> 遍历二叉树 3. 核心思想图解:递归 !寻找最小值 此处用递归实现: !寻找最大值 此处用非递归实现,也可以用递归实现: !是否存在元素x 从root开始往下找,找到含有项X的节点,则此操作返回true,没有找到则返回false。 !插入元素x 从root开始往下找到合适的插入位置,然后插入。 !删除元素x 从root开始往下找到元素x,找到则删除,并且处理好后续工作。 4. BinarySearchTree代码实现 类中

《算法》笔记 8 - 二叉查找树

99封情书 提交于 2019-11-30 18:01:52
二叉查找树 查找 插入 性能 有序性相关的操作 最大键、最小键 向上取整、向下取整 选择、排名 范围查找 删除操作 删除最大键、最小键 通用删除操作 二叉查找树 前面了解的无序链表和有序数组在性能方面至少在线性级别,无法用于数据量大的场合。接下来要学习的二叉查找树可以将链表插入的灵活性和有序数组查找的高效性结合起来,是计算机科学中最重要的算法之一。 一个二叉查找树(Binary Search Tree)是一颗二叉树,其中每个结点都含有一个Comparable的键,以及相关联的值,且每个结点的键都大于其左子树中任意结点的键,小于右子树中任意结点的键。 查找 在二叉查找树中查找时,如果树是空的,则查找未命中;如果被查找的键和根结点的键相等,查找命中,否则就递归地在子树中继续查找,如果被查找的键小于根结点,就选择左子树,否则选择右子树。 查找算法的代码实现为: public class BST<Key extends Comparable<Key>, Value> { private Node root; private class Node { private Key key; private Value val; private Node left, right; public int size; public Node(Key key, Value val, int size) {