查找 与 树(未完成)
来源:互联网 发布:24芯三网合一网络箱 编辑:程序博客网 时间:2024/06/06 03:33
前记:
1 查找
1.1 符号表
- 插入(put),即将一组新的键值对存入表中;
- 查找(get),即根据给定的键得到相应的值。
1.1.1 基础
1.1.2 顺序查找
1.1.3 二分查找
1.2 二叉查找树
1.2.1 定义及实现
1.2.1.1 定义
1.2.1.2 实现
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
1.2.1.2.1 数据表示
1.2.1.2.1.1 构造实现
- 命中:含有该键的节点存在于表中,我们的查找就命中了,然后返回相应的值。
- 未命中:返回null
- 如果树是空的,则查找未命中。
- 如果被查找的键和根节点的键相等,查找命中。
- 否则,就递归地在适当的子树中继续查找。
public class BST<Key extends Comparable<Key>, Value> { private Node root; // root of BST private class Node { private Key key; // sorted by key private Value val; // associated data private Node left, right; // left and right subtrees private int N; // number of nodes in subtree public Node(Key key, Value val, int N) { this.key = key; this.val = val; this.N = N; } } // is the symbol table empty? public boolean isEmpty() { return size() == 0; } // return number of key-value pairs in BST public int size() { return size(root); } // return number of key-value pairs in BST rooted at x private int size(Node x) { if (x == null) return 0; else return x.N; } public Value get(Key key) public void put(Key key, Value val)}
1.2.1.2.2 查找
二叉查找树的查找方法(java 版本)// does there exist a key-value pair with given key? public boolean contains(Key key) { return get(key) != null; } // return value associated with the given key, or null if no such key exists public Value get(Key key) { return get(root, key); } private Value get(Node x, Key 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.1.2.3 插入
二叉查找树的插入(排序)方法public void put(Key key, Value val) { if (val == null) { delete(key); return; } root = put(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.N = 1 + size(x.left) + size(x.right); return x; }
1.2.2 分析
- 最好情况,一棵含有N个结点的树是完全平衡的,每条空链接和根节点的距离都为~lgN。
- 最坏情况,搜索路径上可能有N个结点。
- 在一般情况下的形状和最好情况更接近。
1.2.3 有序性相关的方法与删除
1.2.4 一种可比拟的列表-跳表
1.3 平衡查找树
- 平衡二叉查找树:其一,保证树的深度是O(logN),如果二叉树足够平衡,则深度足够少。
- 其二,(2-3树)之所以能够保证在最差的情况下的效率的原因在于其插入之后仍然能够保持平衡状态。
class TreeNode{private:TreeItemType smallItem,largeItem;TreeNode *leftChildPtr,middleChildPtr,rightChildPtr;friend class TwoThreeTree;};
1.3.1 2-3查找树
1.3.1.1 定义及优势
1.3.1.1.1 定义
1.3.1.1.2 优势
2-3树的查找效率与树的高度是息息相关的。
- 在最坏的情况下,也就是所有的节点都是2-node节点,查找效率为lgN
- 在最好的情况下,所有的节点都是3-node节点,查找效率为log3N约等于0.631lgN
- 1百万个节点的2-3树,树的高度为12-20之间,对于10亿个节点的2-3树,树的高度为18-30之间。
1.3.1.1.3 为什么要这样排列?
因为它是balanced的!一棵高度为k的2-3 tree有2k – 1 到 3k – 1 之间的叶;一棵有elements 为n的2-3 tree 高度最小为 1+log3n, 最大为 1+log2n。它的检索时间为O(logn)。
伪代码如下:
LOOP until curr = nilIF ( data = curr.small OR data = curr.large ) Return currELSE IF ( data < curr.small ) curr = curr.leftELSE IF ( data > curr.small AND data < curr.large ) curr = curr.middleELSE curr = curr.large
1.3.1.2 查找
2-3树的查找和二叉查找树类似,要确定一个树是否属于2-3树,我们首先和其跟节点进行比较,如果相等,则查找成功;否则根据比较的条件,在其左中右子树中递归查找,如果找到的节点为空,则未找到,否则返回。
- 二叉树按照升序插入10个key会得到高度为9的一棵最差树,2-3Tree的高度为2.
- 含有10亿个结点的一棵2-3树的高度仅在19-30之间。(也就是说,访问最多30个结点可查)
1.3.1.2.1 插入
对于2-3 tree,所有的插入(新值)都必须发生在leaf。所以,首先找到新值应该所在的leaf,然后根据这个leaf的情况做出判断:
1. 该点只有一个元素。直接加入就可以了,判断是small还是large。
2. 该点full(small和large都有值),其父结点不是full。那就split该结点,并把中间值推上去。
3. 该点和其父结点都full。如果父结点full,表示父结点已经有3个子树。那就需要一直split 并一直往上推,直到发生以下情况:
1) 父结点最多只有3个子树
2) 父结点是根,创建一个新root,保存中间值。树的高度增加1
1.3.1.2.2 往一个2-node节点插入
往2-3树中插入元素和往二叉查找树中插入元素一样,首先要进行查找,然后将节点挂到未找到的节点上。2-3树之所以能够保证在最差的情况下的效率的原因在于其插入之后仍然能够保持平衡状态。如果查找后未找到的节点是一个2-node节点,那么很容易,我们只需要将新的元素放到这个2-node节点里面使其变成一个3-node节点即可。但是如果查找的节点结束于一个3-node节点,那么可能有点麻烦。
1.3.1.2.3 往一个3-node节点插入
往一个3-node节点插入一个新的节点可能会遇到很多种不同的情况,下面首先从一个最简单的只包含一个3-node节点的树开始讨论。- 新建插入,临时将新键存入该节点中,使之成为4-结点。
- 3-key 4-link,为了容易转化为一棵由3个2-node组成的2-3 Tree
1.3.1.2.4 向节点是3-node,父节点是2-node中插入新键
- 新建插入,临时将新键存入该节点中,使之成为4-结点。
- 3-key 4-link,为了容易转化为一棵由3个2-node组成的2-3 Tree
- 将上述的父节点(3.1.2.2中分解出的父节点)与其真正的父节点(2-node)合并。
1.3.1.2.5 节点是3-node,父节点也是3-node
1.3.1.2.6 分解根节点
1.3.1.2.5 汇总
1.3.1.2.5.1 局部变换
1.3.1.2.5.2 全局性质
1.3.1.2.5.3 2-3树的实现
1.3.1.3 一些扩展
- Gross, R. Hernández, J. C. Lázaro, R. Dormido, S. Ros (2001). Estructura de Datos y Algoritmos. Prentice Hall. ISBN 84-205-2980-X.
- Aho, Alfred V.; Hopcroft, John E.; Ullman, Jeffrey D. (1974). The Design and Analysis of Computer Algorithms. Addison-Wesley., p.145-147
1.3.1.3.1 2-3-4 树
1.3.1.3.2 Finger 树
1.3.1.3.3 2-3 堆
1.3.1.3.4 (a,b)-树
1.3.2 红黑二叉查找树
- 红链接:将2个2-Node链接起来构成一个3-Node
- 黑链接:2-3树中普通的链接。
1.4 散列表
1.4.1 散列函数
1.4.2 各种散列表
1.4.3 数组与内存
1.5 应用
- 在基因组数据中需找分子标记或模式从而绘制全基因组图谱
- 网络信息的组织,从搜索在线贸易到数字图书馆
- 互联网基础架构的实现,例如包在网络节点中的路由、共享文件系统和流媒体
1.5.1 符号表的选择
1.5.2 集合API
1.5.3 字典类用例
1.5.4 索引类用例
1.5.5 稀疏向量
1.6 来源
1.7 后记
- 查找 与 树(未完成)
- LeetCode基础-查找-平衡二叉查找树(红黑树)--未完成
- 树与图(图 未完成)
- 【微软面试题01】二元查找树转换为双向链表(未完成)
- (未完成)社会科学与数学
- REST与Spring mvc(未完成)
- 未完成--字典--《数据结构与算法》
- 《数据库技术与应用》读书笔记-未完成
- 链表中递归查找元素,非递归查找元素 以及基数排序(未完成)josephus问题(未完成)
- Linux设备树-未完成
- 二叉树(未完成)
- 未完成
- 未完成
- 未完成
- 未完成
- 未完成
- 未完成
- 未完成
- 一直以来伴随我的一些学习习惯(刘未鹏)——整理笔记
- E2014_4_18
- NYOJ275对花的烦恼
- 提取安卓的Linux内核和驱动
- java中怎么判断一个字符串在另外一个字符串中的方法
- 查找 与 树(未完成)
- 利用二叉树先序遍历求含n个元素的集合的幂集(used stack and vector)
- 网络POS机如何让信用卡活跃起来的
- Windows下openssl的编译安装 (转)
- Photoshop轻松制作Apple网站导航条按钮
- Linux ps 简介
- String类的替换操作
- 网购返利
- 工作学习整理