使用二叉搜索树实现一个简单的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 - 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. ...
随机推荐
- 微交互:App成功的秘诀
以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 最好的产品拥有两个很棒的特点:功能和细节.产品的功能可成功吸引到人们的注意力,而产品的细节则可留住你 ...
- appium镜像设置
npm --registry http://registry.cnpmjs.org install -g appium 使用npm的国内镜像可以安装,速度很不错. 以后不想输入ip的话可以输入以下命令 ...
- ldap域账号登录
$host = "iflytek.com"; $user = 'yimiao@'.$host;//'用户名@域名'; $pswd = "******"; //1 ...
- Hdu1874 畅通工程续 2017-04-12 18:37 48人阅读 评论(0) 收藏
畅通工程续 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submiss ...
- 用 Servlet 进行上载的原理和实现
Servlet 是用 Java 编写的.协议和平台都独立的服务器端组件,使用请求/响应的模式,提供了一个基于 Java 的服务器解决方案.使用 Servlet 可以方便地处理在 HTML 页面表单中提 ...
- 動態修改 XML 欄位
/* -- for test DECLARE @content VARCHAR(50) DECLARE @folioId VARCHAR(50) DECLARE @opinionType VARCHA ...
- Android-进程理解/进程的优先级别
进程理解 Android系统最小的控制单元是:进程 process 应用/CPU最小的控制单元是:线程 thread 一个应用一个 process 进程 一个应用一个 package(包是唯一的) 一 ...
- View Pi's Status on WebBrowser
1. install php and cgi support sudo apt-get install php5-common sudo apt-get install php5-cgi sudo a ...
- ubuntu16.04 安装jdk 错误解决
错误 $ apt-get install openjdk-9-jdk Errors were encountered while processing: /var/cache/apt/archives ...
- 介绍 ASP.NET Identity - ASP.NET 应用程序的成员身份认证系统
ASP.NET Identity 是构建 ASP.NET web 应用程序的一种新的身份认证系统.ASP.NET Identity 可以让您的应用程序拥有登录功能,并可以轻松地自定义登录用户的相关数据 ...