182Java8利用二叉查找树实现Map
Posted zhangchao19890805
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了182Java8利用二叉查找树实现Map相关的知识,希望对你有一定的参考价值。
本文利用二叉查找树写了一个Map,用来保存键值对。
二叉查找树的定义
二叉查找树又名二叉搜索树,英文名称是 Binary Search Tree,缩写BST。
二叉排序树,英文名称是 Binary Sorted Tree,缩写BST。
二叉查找树、二叉搜索树、二叉排序树,这三者是一回事,只是名字不同。
二叉查找树的定义如下:
二叉查找树或者是一棵空树,或者是具有下列性质的二叉树:
-
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
-
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
-
它的左、右子树也分别为二叉查找树。
二叉查找树的时间复杂度和空间复杂度
Java8代码实现
二叉查找树的节点类:
package zhangchao.bst;
/**
*
* 二叉查找树的节点类。
*
* @author zhangchao
*
* @param <K> 二叉查找树的键。
* @param <V> 二叉查找树的值。
*/
public class BstTreeMapNode<K,V>
// 键
public K key = null;
// 值
public V value = null;
// 父节点的引用。
public BstTreeMapNode parent = null;
// 左子节点的引用。
public BstTreeMapNode left = null;
// 右子节点的引用。
public BstTreeMapNode right = null;
二叉查找树写的 BstTreeMap
package zhangchao.bst;
import java.util.*;
/**
* 利用二叉查找树实现的Map
*
* @author zhangchao
*
* @param <K> 键
* @param <V> 值
*/
public class BstTreeMap<K, V>
// 根节点
private BstTreeMapNode root = null;
// 用户自定义的比较器
private Comparator<K> comparator;
/**
* 构造方法
* @param comparator 用户自定义的比较器
*/
public BstTreeMap(Comparator<K> comparator)
this.comparator = comparator;
/**
* 向map中放入键值对
* @param key 键
* @param value 值
*/
public void put(K key, V value)
if (null == root)
root = new BstTreeMapNode<K, V>();
root.parent = null;
root.key = key;
root.value = value;
return;
BstTreeMapNode<K, V> parent = null;
BstTreeMapNode<K, V> current = root;
int compareResult = 0;
while (null != current)
compareResult = this.comparator.compare(key, current.key);
if (compareResult < 0)
parent = current;
current = current.left;
else if (compareResult > 0)
parent = current;
current = current.right;
else
// 有相等的key,直接设置值就可以了。
current.value = value;
return;
BstTreeMapNode<K, V> newItem = new BstTreeMapNode<K, V>();
newItem.key = key;
newItem.value = value;
newItem.parent = parent;
if (compareResult < 0)
parent.left = newItem;
else if (compareResult > 0)
parent.right = newItem;
/**
* 根据键获取值
* @param key 键
* @return 值
*/
public V get(K key)
BstTreeMapNode<K, V> current = root;
int compareResult;
while (null != current)
compareResult = this.comparator.compare(key, current.key);
if (compareResult < 0)
current = current.left;
else if (compareResult > 0)
current = current.right;
else
// 有相等的key,直接返回值就可以了。
return current.value;
return null;
/**
* 获取键的列表,按照比较器的顺序排列。
* @return 键的列表,按照比较器的顺序排列。
*/
public List<K> keyList()
if (null == root)
return new ArrayList<K>();
List<K> result = new ArrayList<K>();
Stack<BstTreeMapNode> stack = new Stack<>();
BstTreeMapNode<K, V> current = root;
do
while (null != current)
stack.push(current);
current = current.left;
current = stack.pop();
result.add(current.key);
current = current.right;
while (!stack.isEmpty() || null != current);
return result;
/**
* 是否为空。
* @return true表示为空;false表示不为空。
*/
public boolean isEmpty()
return null == root;
/**
* 根据键获取 BST 树的节点。
* @param key 键
* @return BST树的节点
*/
public BstTreeMapNode<K, V> getNode(K key)
BstTreeMapNode<K, V> current = root;
int compareResult;
while (null != current)
compareResult = this.comparator.compare(key, current.key);
if (compareResult < 0)
current = current.left;
else if (compareResult > 0)
current = current.right;
else
// 有相等的key,直接返回值就可以了。
return current;
return null;
/**
* 根据键删除键值对。
* @param key 键
*/
public void remove(K key)
BstTreeMapNode<K, V> node = getNode(key);
if (null == node)
return;
// 叶子节点
if (null == node.left && null == node.right)
if (node == root)
this.root = null;
else if (node == node.parent.left)
node.parent.left = null;
else if (node == node.parent.right)
node.parent.right = null;
node.parent = null;
// 只有左子节点
else if (null != node.left && null == node.right)
if (node == root)
this.root = node.left;
else if (node == node.parent.left)
node.parent.left = node.left;
else if (node == node.parent.right)
node.parent.right = node.left;
node.left.parent = node.parent;
node.parent = null;
node.left = null;
// 只有右子节点
else if (null == node.left && null != node.right)
if (node == root)
this.root = node.right;
else if (node == node.parent.left)
node.parent.left = node.right;
else if (node == node.parent.right)
node.parent.right = node.right;
node.right.parent = node.parent;
node.parent = null;
node.right = null;
// 不是根节点并且有左右子节点。
else
BstTreeMapNode<K,V> current = node.left;
while (null != current.right)
current = current.right;
if (current == current.parent.left)
current.parent.left = current.left;
else if (current == current.parent.right)
current.parent.right = current.left;
if (null != current.left)
current.left.parent = current.parent;
current.parent = node.parent;
current.left = node.left;
current.right = node.right;
if (null != node.left)
node.left.parent = current;
if (null != node.right)
node.right.parent = current;
if (null == node.parent)
this.root = current;
else if (node == node.parent.left)
node.parent.left = current;
else if (node == node.parent.right)
node.parent.right = current;
// 清理被删除节点的关联引用
node.left = null;
node.right = null;
node.parent = null;
/**
* 计算map的键值对数量。
* @return map的键值对数量。
*/
public int size()
return this.keyList().size();
/**
* 清空map,删除所有的键值对。
*/
public void clear()
List<K> keyList = this.keyList();
if (null != keyList && !keyList.isEmpty())
for (K key : keyList)
this.remove(key);
private void showTree(BstTreeMapNode node, int level, String prefix)
if (null == node)
return;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++)
sb.append(" ");
sb.append(prefix);
sb.append(node.key).append(" ");
if (node.parent != null)
sb.append(node.parent.key);
System.out.println(sb);
level++;
showTree(node.left, level, "left : ");
showTree(node.right, level, "right: ");
/**
* 打印树形结构。
*/
public void showTree()
if (null == root)
System.out.println("null");
showTree(root, 0, "root: ");
测试例子
TestBST
package zhangchao.bst;
import java.util.Comparator;
import java.util.List;
public class TestBST
public static void test1()
BstTreeMap<Integer, String> map = new BstTreeMap<>( (o1, o2) -> (o1 - o2) );
int[] arr = new int[]8,3,6,1,2,98,2,6;
for (int i : arr)
map.put(i, "__" + String.valueOf(i));
System.out.println(map.get(3));
System.out.println(map.get(6));
System.out.println(map.get(98));
List<Integer> keyList = map.keyList();
for (Integer key : keyList)
String value = map.get(key);
System.out.println(key + " : " + value);
System.out.println();
map.showTree();
map.remove(2);
System.out.println(map.get(2));
public static void test2()
BstTreeMap<String, String> map = new BstTreeMap(new Comparator<String>()
@Override
public int compare(String o1, String o2)
if (null == o1 && null == o2)
return 0;
if (null == o1 && null != o2)
return -1;
if (null != o1 && null == o2)
return 1;
return o1.compareTo(o2);
);
String[] arr = "j", "h", 以上是关于182Java8利用二叉查找树实现Map的主要内容,如果未能解决你的问题,请参考以下文章