【数据结构】搜索树&Map&Set

目录

1.搜索树

1.1概念

1.2查找

1.3插入

1.4删除

2.Map

2.1map说明

2.2TreeMap和HashMap

2.3常用方法

3.Set

3.1set说明

3.2TreeSet和HashSet

3.3常用方法


1.搜索树

1.1概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者具有以下性质:

1> 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

2> 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

3> 它的左右子树也分别为二叉搜索树

1.2查找

java 复制代码
public class BinarySearchTree {
    static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }
    public TreeNode root;//根结点

    public TreeNode search(int val) {
        TreeNode cur = root;
        while (cur != null) {
            if (cur.val < val) {
                cur = cur.right;
            } else if (cur.val > val) {
                cur = cur.left;
            } else {
                return cur;
            }
        }
        return null;
    }
}

1.3插入

从根节点开始,比根结点小向左走,比根结点大向右走,直到达到叶子结点,插入该叶子结点。

java 复制代码
public boolean insert(int key) {
    TreeNode node = new TreeNode(key);
    //第一次插入
    if (root == null) {
        root = node;
        return true;
    }
    //之后的插入
    TreeNode cur = root;
    TreeNode parent = null;//用来记录cur的位置
    while (cur != null) {
        if (cur.val < key) {
            parent = cur;
            cur = cur.right;
        } else if (cur.val > key) {
            parent = cur;
            cur = cur.left;
        }else { //相同数据不能插入
            return false;
        }
    }
    if (parent.val > key) {
        parent.left = node;
    }else {
        parent.right = node;
    }
    return true;
}

1.4删除

方法:替罪羊删除法

找到左树的最右边,即左树最大值,或找到右树的最左边,即右树的最小值 作为替罪羊。

java 复制代码
/**
 * @param cur 要删除的结点
 * @param parent 要删除节点的父节点
 */
private void remove(TreeNode cur, TreeNode parent) {
    if(cur.left == null) { //1.cur的左树为空
        if(cur == root) {
            root = cur.right;
        }else if(cur == parent.left) {
            parent.left = cur.right;
        }else {
            parent.right = cur.right;
        }

    }else if(cur.right == null) { //2.cur的右树为空
        if(cur == root) {
            root = cur.left;
        }else if(cur == parent.left) {
            parent.left = cur.left;
        }else {
            parent.right = cur.left;
        }

    }else { //3.cur的左右树都不为空
        //方法:替罪羊删除法
        //找右树的最小值,即右树的最左边作为替罪羊
        TreeNode targetParent = cur;
        TreeNode target = cur.right;
        while (target.left != null) { //直到左树为空,说明已经找到了替罪羊
            targetParent = target;
            target = target.left;
        }
        cur.val = target.val; //覆盖
        //回到了上面的情况1和情况2
        if(target == targetParent.left) {
            targetParent.left = target.right;
        }else {
            targetParent.right = target.right;
        }
    }
}

Set中存储key,Map中存储Key-value键值对

2.Map

2.1map说明

Map官方文档:Map (Java Platform SE 8 )

注意:

1.Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或HashMap;

2.Map中存放键值对的Key是唯一的,value是可重复的;

3.在TreeMap中插入键值对时,key不能为空,否则会抛出NullPointerException异常,value可以为空。但HashMap的key和value都可以为空;

  1. Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复);

  2. Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。

  3. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。

2.2TreeMap和HashMap

Map TreeMap HashMap
底层结构 红黑树 哈希桶
增删查改复杂度 O(logN) O(1)
是否有序 关于key有序 无序
是否线程安全 不安全 不安全
增删查改区别 需要进行元素比较 通过哈希函数计算哈希地址
比较与覆写 key必须可比较,否则会抛出ClassCastException异常 自定义类型需要覆写equals和hashCode方法
应用场景 需要在key有序场景下 key是否有序不关心,需要更高的时间性能

2.3常用方法

方法 说明
V get (Object key ) 返回key对应的value
V getOrDefault (Object key, V defaultValue) 返回key对应的value, key不存在返回默认值
V put (K key, V value) 设置key对应的value
V remove (Object key) 删除key对应的映射关系
Set<K> keySet () 返回所有 key 的不重复集合
Collection<V> values () 返回所有 value 的可重复集合
Set<Map.Entry<K, V>> entrySet () 返回所有的 key-value 映射关系
boolean containsKey (Object key) 判断是否包含 key
boolean containsValues (Object value) 判断是否包含 value

3.Set

3.1set说明

Set官方文档:Set (Java Platform SE 8 )

注意:

  1. Set是继承自Collection的一个接口类;

  2. Set中只存储key,并且要求key一定要唯一;

  3. TreeSet的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的;

  4. Set最大的功能就是对集合中的元素进行去重;

  5. 实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序;

  6. Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入;

  7. TreeSet中不能插入null的key,HashSet可以。

3.2TreeSet和HashSet

类TreeMap和HashMap:

Set底层结构 TreeSet HashSet
底层结构 红黑树 哈希桶
增删查改时间复杂度 O(logN) O(1)
是否有序 关于key有序 不一定有序
线程安全 不安全 不安全
增删查改区别 按照红黑树的特性进行插入和删除 先计算key哈希地址,再进行插入和删除
比较与覆写 key必须可比较,否则会抛出ClassCastException异常 自定义类型需要覆写equals和hashCode方法
应用场景 需要在key有序场景下 key是否有序不关心,需要更高的时间性能

3.3常用方法

方法 说明
boolean add ( E e ) 添加元素,但重复元素不会被添加成功
void clear () 清空集合
boolean contains ( Object o ) 判断 o 是否在集合中
Iterator<E> iterator () 返回迭代器
boolean remove ( Object o ) 删除集合中的 o
int size () 返回 set 中元素的个数
boolean isEmpty () 检测 set 是否为空
Object [] toArray () 将 set 中的元素转换为数组返回
boolean containsAll ( Collection<?> c ) 判断集合 c 中的元素是否在 set 中全部存在
boolean addAll ( Collection<? extends E> c ) 将集合c中的元素添加到 set 中,达到去重效果
相关推荐
小小面试官11 天前
java江湖系列——集合世家争霸(下)
java·开发语言·list·set·map·集合·hashmap
天天向上杰1 个月前
浅显易懂HashMap的数据结构
java·数据结构·算法·哈希算法·hashmap·hash
hrhcode4 个月前
Java集合 HashMap 原理解读(含源码解析)
java·数据结构·spring boot·hashmap
mikey棒棒棒7 个月前
算法练习题25——合并多项式
java·算法·hashmap·哈希·多项式
青山猿7 个月前
HashMap常见面试题
java·开发语言·jvm·hashmap
shyの同学7 个月前
使用LinkedHashMap实现固定大小的LRU缓存
java·缓存·hashmap·lru·linkedhashmap
Dexu78 个月前
【ConcurrentHashMap】JDK1.7版本源码解读与分析
hashmap·jdk1.8·jdk1.7
java_t_t8 个月前
TreeMap自定义排序
java·treemap
栗筝i8 个月前
Java 集合框架:TreeMap 的介绍、使用、原理与源码解析
java基础·r-tree·java集合·treemap·栗筝i 的 java 技术栈
技术管理修行9 个月前
Java核心技术【十八】Java集合框架精讲:List、Set、Map
map·hashmap·arraylist·hashset·treeset·treemap·linkedlist