前言
前面我们分别实现了链表
以及二分搜索树
数据结构,在这里我们将基于之前实现的链表
以及二分搜索树
来实现Map
数据结构;
代码实现
- 定义
Map
通用接口;
/**
* @author Map接口
* on 2023/2/7
*/
public interface Map<K, V> {
/**
* 添加键值对
*
* @param key
* @param value
*/
void add(K key, V value);
/**
* 根据key删除对应的value
*
* @param key
*/
V remove(K key);
/**
* 判断是否包含某个key
*
* @param key
* @return
*/
boolean contains(K key);
/**
* 根据key获取对应的value
*
* @param key
* @return
*/
V get(K key);
/**
* 根据key覆盖对应的value
*
* @param key
* @param newValue
*/
void set(K key, V newValue);
/**
* 获取Map集合大小
*
* @return
*/
int getSize();
/**
* 判断当前Map集合是否为空
*
* @return
*/
boolean isEmpty();
}
- 基于
链表
实现Map
映射;
package com.sjgd.map;
import androidx.annotation.NonNull;
/**
* @author 基于链表结构的Map
* on 2023/2/7
*/
public class LinkedListMap<K, V> implements Map<K, V> {
private class Node {
K key;
V value;
private Node next;
public Node() {
}
public Node(K key, V value) {
this.key = key;
this.value = value;
}
public Node(K key, V value, Node next) {
this.key = key;
this.value = value;
this.next = next;
}
public Node(K key) {
this.key = key;
}
@NonNull
@Override
public String toString() {
return key.toString() + ":" + value.toString();
}
}
private Node dummyHead;
private int size;
public LinkedListMap() {
dummyHead = new Node();
}
private Node getNode(K key) {
Node current = dummyHead.next;
while (current != null) {
if (current.key.equals(key)) {
return current;
}
current = current.next;
}
return null;
}
@Override
public void add(K key, V value) {
Node queryNode = getNode(key);
if (queryNode == null) {
// 根据key没有查到有对应的键值对,直接插入到链表头部
dummyHead.next = new Node(key, value, dummyHead.next);
size++;
} else {
queryNode.value = value;
}
}
@Override
public V remove(K key) {
Node prev = dummyHead;
while (prev.next != null) {
if (prev.next.key.equals(key)) {
break;
}
prev = prev.next;
}
if (prev.next != null) {
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size--;
return delNode.value;
}
return null;
}
@Override
public boolean contains(K key) {
return getNode(key) != null;
}
@Override
public V get(K key) {
return getNode(key) == null ? null : getNode(key).value;
}
@Override
public void set(K key, V newValue) {
Node node = getNode(key);
if (node == null) {
throw new IllegalArgumentException("The Key is not exist!");
}
node.value = newValue;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
}
- 基于
二分搜索树
实现Map
映射;
package com.sjgd.map;
/**
* @author 基于二分搜索树实现的Map集合
* on 2023/2/7
*/
public class BSTMap<K extends Comparable<K>, V> implements Map<K, V> {
private class Node {
private K key;
private V value;
private Node left;
private Node right;
public Node(K key, V value) {
this.key = key;
this.value = value;
}
public Node(K key, V value, Node left, Node right) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
}
}
private Node root;
private int size;
/**
* 向二分搜索树中添加新元素
*
* @param key
* @param value
*/
@Override
public void add(K key, V value) {
root = add(root, key, value);
}
private Node add(Node node, K key, V value) {
if (node == null) {
size++;
return new Node(key, value);
}
if (node.key.compareTo(key) > 0) {
add(node.left, key, value);
} else if (node.key.compareTo(key) < 0) {
add(node.right, key, value);
} else {
node.value = value;
}
return node;
}
/**
* 返回以Node为根节点的二分搜索树中,key所在的节点
*
* @param node
* @param key
* @return
*/
private Node getNode(Node node, K key) {
if (node == null) {
return null;
}
if (node.key.compareTo(key) == 0) {
return node;
} else if (node.key.compareTo(key) > 0) {
return getNode(node.left, key);
} else {
return getNode(node.right, key);
}
}
@Override
public V remove(K key) {
Node node = getNode(root, key);
if (node == null) {
return null;
}
root = remove(root, key);
return node.value;
}
private Node remove(Node node, K key) {
if (node == null) {
return null;
}
if (node.key.compareTo(key) > 0) {
node.left = remove(node.left, key);
return node;
} else if (node.key.compareTo(key) < 0) {
node.right = remove(node.right, key);
return node;
} else {
//相等的情况
//待删除节点左子树为空的情况
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
if (node.right == null) {
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
//当左右子树都存在的时候,找到当前node节点的后继节点【右子树中最小值】
Node successor = getMin(node.right);
//先把右子树添加上,因为当前successor为右子树中最小node,如果先挂左子树,会改变右子树最小node的值
successor.right = removeMin(node.right);
successor.left = node.left;
node.left = node.right = null;
return successor;
}
}
private Node removeMin(Node node) {
if (node.left == null) {
//记录其右子树
Node rightNode = node.right;
//将右子树删除
node.right = null;
size--;
return rightNode;
}
//把删除的右子树添加到上一层的左子树上
node.left = removeMin(node.left);
return node;
}
private Node getMin(Node node) {
if (node.left == null) {
return node;
}
return getMin(node.left);
}
@Override
public boolean contains(K key) {
return getNode(root, key) != null;
}
@Override
public V get(K key) {
Node node = getNode(root, key);
if (node == null) {
return null;
}
return node.value;
}
@Override
public void set(K key, V newValue) {
Node node = getNode(root, key);
if (node == null) {
throw new IllegalArgumentException("This key is not exist!");
}
node.value = newValue;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
}
时间复杂度比较
基于链表实现的Map映射:O(n);
基于二分搜索树实现的Map映射:平均为O(logn),最坏情况【退化为链表】为O(n);
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )