之前看了刘新宇大大的《算法新解》有了点收获,闲来无事,便写了一个二叉搜索树实现的Map类。

java的Map接口有很多不想要的方法,自己定义了一个

 public interface IMap<K, V> {
V get(K k); void put(K k, V v); V remove(K k);
}

具体实现:

 public class BSTree<K, V> implements IMap<K, V> {
Entry<K, V> head = null; @Override
public V get(K k) {
return get(head, k);
} private V get(Entry<K, V> node, K k) {
if (node == null) {
return null;
}
int compare = compare(node.key, k);
if (compare == 0) {
return node.value;
} else if (compare > 1) {
return get(node.right, k);
} else {
return get(node.left, k);
}
} @Override
public void put(K k, V v) {
//1.head is null
if (head == null) {
head = new Entry<>(k, v, null);
}
//2.head is not null
else {
put(head, k, v);
}
} private void put(Entry<K, V> node, K k, V v) {
int compare = compare(node.key, k);
if (compare == 0) {
node.value = v;
} else if (compare > 1) {
if (node.right == null) {
node.right = new Entry<>(k, null, node);
}
put(node.right, k, v);
} else {
if (node.left == null) {
node.left = new Entry<>(k, null, node);
}
put(node.left, k, v);
}
} private int compare(K key, K k) {
return ((Comparable) key).compareTo(k);
} @Override
public V remove(K k) {
return remove(head, k);
} private V remove(Entry<K, V> node, K k) {
if (node == null) {
return null;
}
int compare = compare(node.key, k);
if (compare == 0) {
//1.no child
if (node.left == null && node.right == null) {
if (node.parent == null)
head = null;
else if (node == node.parent.left) {
node.parent.left = null;
} else {
node.parent.right = null;
}
return node.value;
}
//2.has right child
else if (node.right != null) {
V oldValue = node.value;
Entry<K, V> newNode = findMin(node.right);
node.key=newNode.key;
node.value = newNode.value;
newNode.parent.right = null;
return oldValue;
}
//3.has no right child,has left child
else{
V oldValue = node.value;
Entry<K, V> newNode = findMax(node.left);
node.key=newNode.key;
node.value = newNode.value;
newNode.parent.left= null;
return oldValue;
} } else if (compare > 0) {
return remove(node.right, k);
} else {
return remove(node.left, k);
}
} private Entry<K, V> findMax(Entry<K, V> left) {
if (left.right == null) {
return left;
}else{
return findMax(left.right);
}
} private Entry<K, V> findMin(Entry<K, V> right) {
if (right.left == null) {
return right;
}else {
return findMin(right.left);
}
} class Entry<K, V> {
K key;
V value;
Entry<K, V> left;
Entry<K, V> right;
Entry<K, V> parent; private Entry(K key, V value, Entry<K, V> parent) {
this.key = key;
this.value = value;
left = null;
right = null;
this.parent = parent;
}
} }

测试的类:

 public class BSTreeTest {
private static int write_num = 100_0000;
private static int read_num = 100_0000; public static void main(String[] args) {
// IMap<String,Integer> map = new BSTree();
// Map<String, Integer> map = new TreeMap<>();
// Map<String, Integer> map = new HashMap<>();
Map<String, Integer> map = new LinkedHashMap<>();
long start = System.nanoTime();
for (int i = 0; i < write_num; i++) {
map.put("" + i, i);
}
for (int i = 0; i < read_num; i++) {
Integer s = map.get(i + "");
assert s.equals(i);
}
for (int i = 0; i < read_num / 2; i++) {
map.remove(i + "");
}
for (int i = 0; i < read_num / 2; i++) {
Integer s = map.get(i + "");
assert s == null;
}
for (int i = read_num / 2; i < read_num / i++; i++) {
Integer s = map.get(i + "");
assert s.equals(i);
}
System.out.println("map cost:" + (System.nanoTime() - start));
}
}

在各自只运行一次的情况下测试数据如下:

map cost:1125174394 //myMap
map cost:812963047 //TreeMap
map cost:475993738 //HashMap
map cost:475993738 //LinkedHashMap

由于二叉搜索树没有自平衡机制,搜索的时间在O(n*n)与O(lgn)之间摇摆,因此对比java用红黑树实现的TreeMap时间O(lgn)要多上很多。

使用二叉搜索树实现一个简单的Map的更多相关文章

  1. [CareerCup] 4.6 Find Next Node in a BST 寻找二叉搜索树中下一个节点

    4.6 Write an algorithm to find the'next'node (i.e., in-order successor) of a given node in a binary ...

  2. LeetCode-450 二叉搜索树删除一个节点

    二叉搜索树 建树 删除节点,三种情况,递归处理.左右子树都存在,两种方法,一种找到左子树最大节点,赋值后递归删除.找右子树最小同理 class Solution { public: TreeNode* ...

  3. LeetCode(98): 验证二叉搜索树

    Medium! 题目描述: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右 ...

  4. 二叉搜索树-php实现 插入删除查找等操作

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...

  5. 「面试高频」二叉搜索树&双指针&贪心 算法题指北

    本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...

  6. Java实现二叉搜索树的插入、删除

    前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...

  7. lintcode: 把排序数组转换为高度最小的二叉搜索树

    题目: 把排序数组转换为高度最小的二叉搜索树 给一个排序数组(从小到大),将其转换为一棵高度最小的排序二叉树. 样例 给出数组 [1,2,3,4,5,6,7], 返回 4 / \ 2 6 / \ / ...

  8. [Data Structure] 二叉搜索树(Binary Search Tree) - 笔记

    1. 二叉搜索树,可以用作字典,或者优先队列. 2. 根节点 root 是树结构里面唯一一个其父节点为空的节点. 3. 二叉树搜索树的属性: 假设 x 是二叉搜索树的一个节点.如果 y 是 x 左子树 ...

  9. LeetCode - 验证二叉搜索树

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. ...

随机推荐

  1. 使用tengine解决负载均衡的session问题

    事情的经过时这样的~~,我看了好多好多百度中nginx负载均衡中解决session问题的方式,我选择了研究url_hash的方式.经过一番配置之后,我越发觉得这百度搜出来的帖子也太过久远了吧,去htt ...

  2. asp.net mvc 5框架揭秘(文摘)

    第1章 asp.net + mvc 1.1.2 什么是MVC模式: model:对应用状态和业务功能的封装,同时包含数据和行为的领域模型. view:实现可视化界面的呈现并捕捉最终用户的交互操作. c ...

  3. 让Asp.Net WebAPI支持OData查询,排序,过滤。(转)

    出处:http://www.cnblogs.com/liuzhendong/p/4233380.html 让Asp.Net WebAPI支持OData后,就能支持在url中直接输入排序,过滤条件了. ...

  4. docker 关于volumns的总结(转)

    原文地址:http://www.cnblogs.com/ivictor/p/4834864.html Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个ce ...

  5. mysql5.7文件无法导入数据库的解决方案

    一般是因为my.ini的“secure-file-priv”的设置导致loaddata失败,网上查了许多资料,大部分都是要求注释掉my.ini的: secure-file-priv="C:/ ...

  6. Hello_Area_Description 任务三:Project Tango采集区域描述数据

    Permission Dialogs for Users in Java在Java中用户使用的权限对话框 Tango works by using visual cues from the devic ...

  7. (连通图 缩点 强联通分支)Popular Cows -- poj --2186

    http://poj.org/problem?id=2186 Description Every cow's dream is to become the most popular cow in th ...

  8. URAL 1996 Cipher Message 3 (FFT + KMP)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意 :给出两个串A , B,每个串是若干个byt ...

  9. CAS实战の自定义注销

    步骤一 在cas server端,设置/WebContent/WEB-INF/cas-servlet.xml: <bean id="logoutAction" class=& ...

  10. pycharm中安装可以贴图片的Markdown插件

    方法一:(测试成功) 先安装官方推荐的Markdown support插件,再安装Paste images into MarkDown 如果Paste images into MarkDown插件在线 ...