【数据结构】搜索树&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 中,达到去重效果
相关推荐
mikey棒棒棒2 个月前
算法练习题25——合并多项式
java·算法·hashmap·哈希·多项式
青山猿2 个月前
HashMap常见面试题
java·开发语言·jvm·hashmap
shyの同学2 个月前
使用LinkedHashMap实现固定大小的LRU缓存
java·缓存·hashmap·lru·linkedhashmap
Dexu73 个月前
【ConcurrentHashMap】JDK1.7版本源码解读与分析
hashmap·jdk1.8·jdk1.7
java_t_t3 个月前
TreeMap自定义排序
java·treemap
栗筝i4 个月前
Java 集合框架:TreeMap 的介绍、使用、原理与源码解析
java基础·r-tree·java集合·treemap·栗筝i 的 java 技术栈
技术管理修行4 个月前
Java核心技术【十八】Java集合框架精讲:List、Set、Map
map·hashmap·arraylist·hashset·treeset·treemap·linkedlist
Flamesky4 个月前
Dotnet算法与数据结构:Hashset, List对比
list·dotnet·hashset
银氨溶液5 个月前
Map集合之HashMap细说
java·开发语言·后端·面试题·集合·hashmap·hash
Benaso5 个月前
HashMap在Go与Java的底层实现与区别
java·数据结构·golang·hashmap