使用二叉搜索树实现一个简单的Map
之前看了刘新宇大大的《算法新解》有了点收获,闲来无事,便写了一个二叉搜索树实现的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的更多相关文章
- [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 ...
- LeetCode-450 二叉搜索树删除一个节点
二叉搜索树 建树 删除节点,三种情况,递归处理.左右子树都存在,两种方法,一种找到左子树最大节点,赋值后递归删除.找右子树最小同理 class Solution { public: TreeNode* ...
- LeetCode(98): 验证二叉搜索树
Medium! 题目描述: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右 ...
- 二叉搜索树-php实现 插入删除查找等操作
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...
- 「面试高频」二叉搜索树&双指针&贪心 算法题指北
本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...
- Java实现二叉搜索树的插入、删除
前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...
- lintcode: 把排序数组转换为高度最小的二叉搜索树
题目: 把排序数组转换为高度最小的二叉搜索树 给一个排序数组(从小到大),将其转换为一棵高度最小的排序二叉树. 样例 给出数组 [1,2,3,4,5,6,7], 返回 4 / \ 2 6 / \ / ...
- [Data Structure] 二叉搜索树(Binary Search Tree) - 笔记
1. 二叉搜索树,可以用作字典,或者优先队列. 2. 根节点 root 是树结构里面唯一一个其父节点为空的节点. 3. 二叉树搜索树的属性: 假设 x 是二叉搜索树的一个节点.如果 y 是 x 左子树 ...
- LeetCode - 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. ...
随机推荐
- wmi收集系统信息 发送到服务器打印
#include "WMIManager.h" #include <vector> #include <string> #include <boost ...
- 一起做RGB-D SLAM(8) (关于调试与补充内容)
“一起做”系列完结后,我收到不少同学给我的反馈.他们提了一些在程序编译/运行过程中的问题.我把它们汇总起来,组成了这个“补充篇”.你也可以看成是一个Q&A. Q: OpenCV的版本?A: 我 ...
- 使用Git 管理heroku的项目(windows)
此过程与管理github中的项目类似,即是普通的git配置 安装 Heroku Toolbelt, 里面包含了 msygit Foreman,以及heroku的命令行界面 1.首先在heroku上新建 ...
- vc++ 不同对话框中传递信息的方法(基于自定义消息SendMessage) (转载)
转载自:http://blog.csdn.net/myj0513/article/details/6827360 背景: 新建了一个基于对话框的MFC程序,在主对话框中添加tabcontrol控件,又 ...
- Oracle EBS FND User Info API
1. 与用户信息相关API PKG. --和用户处理有关的API FND_USER_PKG; --和用户密码处理有关的API FND_WEB_SEC; --和用户职责处理有关的API ...
- Apps: Help > Diagnostics > Custom Code > Personalize 查看LOV中的查询语句
Apps Menu Path: Help > Diagnostics > Custom Code > Personalize 查看LOV中的查询语句 一直有实施顾问询问我XXFo ...
- Zero Clipboard js+swf实现的复制功能使用方法
开发中经常会用到复制的功能,在 IE 下实现比较简单.但要想做到跨浏览器比较困难了.本文将介绍一个跨浏览器的库类 Zero Clipboard .它利用 Flash 进行复制,所以只要浏览器装有 Fl ...
- subprocess.Popen命令如何隐藏弹框
在用PYQT编写GUI界面时,代码中有用到subprocess.Popen(),打包exe后每次遇到subprocess语句是就会弹出命令框,很是头疼, 下面是解决的办法 import subproc ...
- HTTP Error 502.5 - Process Failure Win10 VS可以正常访问,部署本地IIS报错
最近本core得升级导致各种问题,之前刚解决了server2012的502.5问题 今天本机又出现这个问题. 情况描述:VS可以正常调试查看,部署本地IIS访问 错误502.5 分析:VS可以使用II ...
- .net core 自制错误日志
前言 之前.net framework用的ErrorLog帮助类,对于监控错误形成日志,内容非常清晰,想在.net core2.2中继续用,但是有很多不一样的地方,所以想总结一下. 首先需要HttpC ...