3.Set and Map (集合与映射)
// 都可以使用链表和树实现,只要设置 Node 中增加key, Value 即可
Set:不允许出现重复元素
- set实际上是一个接口, 实现了 Collection
主要有以下几个方法:
// 获取元素个数
int size()
// 查看 Set 是否为空
boolean isEmpty()
// 查看 Set 是否包含元素
boolean contains(Object o)
// 添加元素
void add(E e)
// 删除元素
void remove(Object o)
HashSet实现:
public class HashSet
Set<Integer> set = new HashSet<>();// 创建Set,为 AbstractSet<E> 的子类
private transient HashMap<E,Object> map; // 底层由HashMap实现
LinkedList实现:
// 直接调用了 链表自己实现的方法
public class LinkedListSet <E extends Comparable<E>> implements Set<E>{
private LinkedList<E> list;
public LinkedListSet(){
list = null;
}
// 获取元素个数
public int size(){
return list.getSize();
}
// 查看 Set 是否为空
public boolean isEmpty(){
return list.isEmpty();
}
// 查看 Set 是否包含元素
public boolean contains(E value){
return list.contains(value) != null;
}
// 添加元素
public void add(E e){
if(!list.contains(e)){
list.addFirst(e);
}
}
// 删除元素
public void remove(E e){
remove(e);
}
}
BST实现:
// 对于BST实现的 Set
// 由于只有一个val, 所以实际操作和BST 相同
public class BSTSet <E extends Comparable<E>> implements Set<E>{
private BSTSet<E> bstset;
public BSTSet(){
bstset = null;
}
// 获取元素个数
public int size(){
return bstset.getSize();
}
// 查看 Set 是否为空
public boolean isEmpty(){
return bstset.isEmpty();
}
// 查看 Set 是否包含元素
public boolean contains(E value){
return bst.contains(value) != null;
}
// 添加元素
public void add(E e){
if(!bst.contains(e)){
bst.add(e);
}
}
// 删除元素
public void remove(E e){
bst.remove(e);
}
}
Map(键值对):
Map实际上也是接口:
Map<K,V>;
// 主要的方法
// 添加元素
void add(K key , V value);
V remove(K key);// 删除 对应 key
boolean contains(K key); // 查看是否存在 key
V get(K key);// 获取 key对应值
void set(K key, V newValue); // 更新值
int getSize();
boolean isEmpty();
LinkedList 实现 Map
// 在 Node 中分别存入 Map, Value
public class LinkedList<K,V> implements Map<K,V>{
private class Node{
public K key;
public V value;
public Node next;
public Node(K key, V value, Node next){
this.key = key;
this.value = value;
this.next = next;
}
// 放入值可为 null, 但是需要有一个 key 对应
public Node(K key){
this(key, null, null);
}
}
private Node dummyHead;
private int size;
public LinkedListMap() {
dummyHead = new Node(null,null,null);
size = 0;
}
@Override
public int getSize(){
return size;
}
@Override
public boolean isEmpty(){
return size == 0;
}
public Node getNode(K key){
Node res = dummyHead.next;
while(res!=null){
if(res.key.equals(key)){
return res;
}
res = res.next;
}
return null;
}
@Override
public void add(K key, V val){
// 如果不存在 key, 直接加到头部(直接查找是否有对应Node)
// 如果存在,改变value
Node res = getNode(key);
if(res == null){
dummyHead.next = new Node(key, value, dummyHead.next);
size++;
}else{
res.value = val;
}
}
@Override
public void set(K key, V val){
Node node = getNode(key);
if(node == null){
throw new IllegalArgumentException("map don't contains key");
}
node.value = val;
}
@Override
public V remove(K key){
Node node = getNode(key);
if(node == null){
throw new IllegalArgumentException("map don't contains key");
}
Node head = dummyhead;
for(int i = 0; i < size; i++){
if(head.next.key.equals(key)){
break;
}
head = head.next;
}
head.next = node.next;
node.next = null;
size--;
return node.value;
}
@Override
public boolean contains(K key){
return getNode(key) != null;
}
@Override
public V get(K key){
Node node = getNode(key);
if(node == null){
throw new IllegalArgumentException("map don't contains key");
}
return node == null ? null : node.value;
}
}
BST(二分搜索树)实现Map
// 根据 key 存在排序
// 二分搜索树,左子节点val < 父节点 val < 右子节点 val
public class BSTMap <K extend Comparable<K>, V> implements Map<K ,V>{
private class Node{
public K key;
public V value;
public Node left, right;
public Node(K key, V value. Node left, Node right){
this.key = key;
this.value = value;
this.left = left;
this.left = right;
}
// 放入值可为 null, 但是需要有一个 key 对应
public Node(K key){
this(key, null, null, null);
}
}
private Node root;
private int size;
public BSTMap(){
root = null;
size = 0;
}
@Override
public int getSize(){
return size;
}
@Override
public boolean isEmpty(){
return size == 0;
}
@Override
public V get(K key){
Node res = getNode(key);
return res == null ? null : res.value;
}
@Override
public boolean contains(K key){
return getNode(key) != null;
}
// 使用递归方式
public Node getNode(K key){
return getNode(root, key);
}
private Node getNode(Node node, K key){
if(node == null){
return null;
}
if(node.key.compareTo(key) < 0){
return getNode(node.left, key);
}else if(node.key.compareTo(key) > 0){
return getNode(node.right, key);
}
return node;
}
@Override
public void add(K key, V value){
Node res = getNode(key);
if(res == null){
root = add(root, key, value);
size++;
}else{
res.value = value;
}
}
private Node add(Node node, K key, V value){
if(node == null){
return new Node(key, value, null, null);
}
if(node.key.compareTo(key) > 0){
node.right = add(node.right, key, value);
}else{
node.left = add(node.left, key, value);
}
return node;
}
@Override
// 二分搜索树,删除某一结点后,采用前缀或者后缀
// 前缀, 把左子树中最大值交换
// 后缀,把右子树中最小值交换
public V remove(K key){
Node res = getNode(key);
if(res == null){
throw new IllegalArgumentException("map don't contains key");
}
root = remove(root, key);
return res.value;
}
// 获取Node下 最大值
// 当仅有root 节点的时候,最大值为 root
public Node findMax(Node node){
// 获取左子树中最右那个Node
Node res = node;
while(res.right != null){
res = res.right;
}
return res;
}
// 删除Node下最大值,即删除最右的子节点
public Node removeMax(Node node){
Node res = node;
while(node.right != null){
node = node.right;
}
node = null;
size--;
return node;
}
// 若节点是否为叶子节点
// 若非叶子节点,这里使用前缀法,获取左子树中最大值,进行交换
private Node remove(Node node, K key){
if(node.key.compare(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 accessor = node.right;
node.right = null;
size--;
return accessor;
}else if(node.right == null){
Node accessor = node.left;
node.left = null;
size--;
return accessor;
}else{
// 左右子节点均存在
Node accessor = findMax(node);
accessor.right = node.right;
accessor.left = removeMax(node.left);
node.left = null;
node.right = null;
return accessor;
}
}
}
@Override
public void set(K key, V newValue){
if(!contains(key)){
throw new IllegalArgumentException("map don't contains key");
}
Node res = getNode(key);
res.value = newValue;
}
}