二叉查找树总结
来源:互联网 发布:幕墙下料软件 编辑:程序博客网 时间:2024/05/30 07:13
1. 二叉查找树的数据结构
解析:
public class BST<Key extends Comparable<Key>, Value> { private Node root; //二叉查找树的根节点 private class Node { private Key key; //键 private Value val; //值 private Node left, right; //指向子树的链接 private int size; //以该节点为根的子树中的节点总数 public Node(Key key, Value val, int size) { this.key = key; this.val = val; this.size = size; } } // 初始化一个空的符号表 public BST() { } ......}
树由Node对象组成,每个对象都包含有一对键值、两条链接和一个结点计数器N。root变量指向二叉查找树的根节点
Node对象(这棵树包含了符号表中的所有键值对)。其中,size(x)=size(x.left)+size(x.right)=1。
2. 结点插入
解析:
public void put(Key key, Value val) { if (key == null) throw new IllegalArgumentException("calledput() with a null key"); if (val == null) { delete(key); return; } this.root = put(this.root, key, val); assert check();}private Node put(Node x, Key key, Value val) { if (x == null) return new Node(key, val, 1); int cmp = key.compareTo(x.key); if (cmp < 0) x.left = put(x.left, key, val); else if (cmp > 0) x.right = put(x.right, key, val); else x.val = val; x.size = 1 + size(x.left) + size(x.right); return x;}
(1)当根节点为null时直接返回以key和val新建的节点;
(2)如果当被插入的key小于根节点的key时,递归在左子树中执行插入操作;
(3)如果被插入的key大于根节点的key时,递归在右子树中执行插入操作;
(4)如果被插入的key等于根节点的key时更新此根节点的val。
3. 结点查找
解析:
public Value get(Key key) { return get(root, key);}private Value get(Node x, Key key) { if (key == null) throw new IllegalArgumentException("called get() with a null key"); if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) return get(x.left, key); else if (cmp > 0) return get(x.right, key); else return x.val;}
(1)如果键值位于符号表中,那么返回相应的值;
(2)如果键值不在符号表中,那么返回null;
(3)如果为空树,那么直接返回null;
(4)如果被查找的key和根节点相同,那么命中返回根节点对应的val;
(5)如果被查找的key大于根节点的key,那么递归在其右子树上查找;
(6)如果被查找的key小于根节点的key,那么递归在其左子树上查找。
4. 结点删除
解析:
public void delete(Key key) { if (key == null) throw new IllegalArgumentException("called delete() with a null key"); root = delete(root, key); assert check();}private Node delete(Node x, Key key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) x.left = delete(x.left, key); else if (cmp > 0) x.right = delete(x.right, key); else { if (x.right == null) return x.left; if (x.left == null) return x.right; Node t = x; x = min(t.right); x.right = deleteMin(t.right); x.left = t.left; } x.size = size(x.left) + size(x.right) + 1; return x;}
deleteMin函数,如下所示:
public void deleteMin() { if (isEmpty()) throw new NoSuchElementException("Symbol table underflow"); root = deleteMin(root); assert check();}private Node deleteMin(Node x) { if (x.left == null) return x.right; x.left = deleteMin(x.left); x.size = size(x.left) + size(x.right) + 1; return x;}当删除一个有两个子结点的结点时,在删除结点x后用它的后继节点填补它的位置。如下所示:
(1)将指向即将被删除的结点的链接保存为t;
(2)将x指向它的后继节点min(t.right);
(3)将x的右链接(原本指向一颗所有结点都大于x.key的二叉查找树)指向deleteMin(t.right),也就是在删除后所有
结点仍然都大于x.key的子二叉查找树;
(4)将x的左链接(本为空)设为t.left(其下所有的键都小于被删除的结点和它的后继结点)。
5. 时间复杂度分析
解析:
(1)在由N个随机键构造的二叉查找树中,查找命中平均所需的比较次数为2ln(N)约等于1.39lg(N)。
(2)在由N个随机数构造的二叉查找树中,插入操作和查找未命中平均所需的比较次数为2ln(N)约等于1.39lg(N)。
(3)在一棵二叉查找树中,所有操作在最坏情况下所需时间和树的高度成正比。
参考文献:
[1] 算法(第4版):二叉查找树
- 查找:二叉查找树总结
- 二叉查找树-总结
- 二叉查找树总结
- 二叉查找树总结
- 二叉查找树总结
- 二叉查找树BST总结
- 二叉查找树专题总结
- 二叉查找树专题总结
- lintcode 二叉查找树总结
- lintcode二叉查找树总结
- 查找算法总结(3)--二叉查找树
- 二叉查找树的遍历总结
- LeetCode总结 -- 二叉查找树篇
- 学习《算法导论》 二叉查找树 总结
- LintCode-二叉查找树专题总结
- lintcode——二叉查找树总结
- 查找算法总结(4)--平衡二叉树
- 各种二叉树和查找结构总结
- 人群运动--Scene-Independent Group Profiling in Crowd
- Java中ArrayList remove会遇到的坑
- javascript中的原型对象
- 泛型
- 单因素方差分析样例和代码 (One-Way ANOVA)
- 二叉查找树总结
- 在一个千万级的数据库查寻中,如何提高查询效率?
- 数串
- Android中三种锁的用法
- 浅谈浏览器的编码与解码过程
- 运行时修改内存中的Dalvik指令来改变代码逻辑
- 图片中添加点击事件后没有反应的问题分析
- Unity3D_touch事件和点击事件
- SCUT Training 20170913 Problem N