大数据算法系列4:二叉树,红黑树和B树
概述: 用于数据查找(搜索)的数据结构
前面的文章系列,我们都是讲排序,这次我们来讲讲另外一个应用场景: 数据搜索。
- 散列表
- 布隆过滤器
- 二叉树
- 红黑树
- B树
一. 散列表
通过hash函数,将数据均匀的分布在不同的bucket中,这样就大大减少了数据检索的时间。
image.png散列函数:
散列表的性能取决于散列函数,散列函数决定了可以把原始数据集分布到多少的桶中。
动态散列表:
二. 布隆过滤器
布隆过滤器这个使用场景是比较多的。
原理是使用n个hash函数,然后分别对原始数据进行计算后存储hash函数计算之后的值。
如果它们有一个说元素不在集合中,那肯定就不在。
但是因为不同数值的hash值可能一致,所以当布隆过滤器判断数值在集合中存在的时候,不一定真的就存在,需要通过其它数据结构,再进行判断。
而且,当数据量越来越大,布隆过滤器的准确率也就越来越低。
image.png三. 二叉树
3.1 二叉树
左边小于父节点的值
右边大于等于父节点的值
image.png
二叉树的弱点:
基于二叉查找树的这种特点,在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点。n 个节点的二叉树,正常情况下,查找的时间复杂度为 O(logN)。之所以说是正常情况下,是因为二叉查找树有可能出现一种极端的情况,例如:
这种情况虽也满足二叉树的条件,但已经近似退化为一条链表,这样的二叉树的查找时间复杂度顿时变成了 O(n)。所以必须防止这种情况发生,于是引申出了平衡二叉树。
3.2 平衡二叉树
-
平衡二叉树是基于二分法的策略提高数据查找速度的二叉树的数据结构。
-
平衡二叉树是采用二分法思维把数据按规则组装成一个树形结构的数据,用这个树形结构的数据减少无关数据的检索,大大的提升了数据检索的速度。平衡二叉树的数据结构组装过程有以下规则:
2.1) 非叶子节点只能允许最多两个子节点存在。
2.2 ) 每一个非叶子节点数据分布规则为左边的子节点小当前节点的值,右边的子节点大于当前节点的值(这里值是基于自己的算法规则而定的,比如 hash 值)。 -
平衡二叉树特点:
3.1) 非叶子节点最多拥有两个子节点。
3.2) 非叶子节点值大于左边子节点、小于右边子节点。
3.3)树的左右两边的层级数相差不会大于 1。
3.4)没有值相等重复的节点。
右边的二叉树,如果是平衡二叉树的话,就会通过旋转,变化为左边的平衡二叉树。
image.png
四. 红黑树
虽然平衡树解决了二叉查找树退化为近似链表的缺点,能够把查找时间控制在 O(logn),却不是最佳的。因为平衡树要求每个节点的左子树和右子树的高度差至多等于 1,这个要求太严,导致每次进行【插入/删除】节点的时候,几乎都会破坏平衡树的第二个规则,进而都需要通过左旋和右旋来进行调整,使之再次成为一颗符合要求的平衡树。
image.png五. B树
节点
树形
B树索引的弱点:
六. 实例
http://poj.org/problem?id=2503
package com.suanfa.数据结构;
import java.util.Scanner;
import java.util.Hashtable;
public class POJ2503 {
public static void main(String[] args) {
Scanner in = new Scanner( System.in );
Hashtable<String, String> table = new Hashtable<String, String>();
String input;
String [] array = new String[2];
while (in.hasNext()){
input = in.nextLine();
if (input.length()==0) break;
array = input.split( " " );
table.put( array[1], array[0] );
}
while (in.hasNext()){
input= in.nextLine();
if (table.get( input ) != null) System.out.println(table.get( input ));
else System.out.println("eh");
}
}
}