1、搜索树
二叉搜索树又称为二叉排序树。要么时空树,要么具有以下性质的二叉树。
->当左右子树不为空的情况下,左子树上所有节点的值都小于根节点的值,右子树上所有节点的值都大于根节点的值。
->它的左右子树也分别为二叉搜索树。
1-1 查找
利用其左边比它小,右边比他大的性质进行查找。
较一般的二叉树简单。
1-2 插入节点
结果:
1-3 删除节点
先找到要删除的节点,对于要删除的节点,考虑一侧是空树和两侧都不是空的情况。
两侧都不为空 -> 采用替换删除的方法,【直接覆盖】,取右树的最小值/左树的最大值进行替换
代码实现:
左侧为找要删除的节点,右侧则开始进行删除
2、Map
Map与Set
->Map是一个接口,不能直接实例化对象,如果要实例化对象,只能实例化其实现类TreeMap或者HashMap
->Map重写了toString方法
->一些方法:
V get(Object key) //返回 key 对应的 value
V put(K key, V value) //设置 key 对应的 value
V remove(Object key) //删除 key 对应的映射关系
boolean containsKey(Object key) //判断是否包含 key
-> 里边存储可比较的key值
比如下例:放入的顺序与打印的顺序不一样
->如果存储一样的key值,后面存的会把之前的覆盖。【Map中存放键值对,key值唯一】
->如果想拿到value值,用get()方法;如果map里边没有要找的,返回null
3、Set
->Set中只存储了Key,并且key唯一
->Set中存储的是不重复的元素,应用场景:对集合中的元素进行去重
->当中存储的元素,必须是可比较的。
->TreeSet不能插入null的key
->TreeSet底层是红黑树,HashSet底层是哈希桶
->一些方法:
boolean add(E e) //添加元素,但重复元素不会被添加成功
void clear() //清空集合
boolean contains(Object o) //判断 o 是否在集合中
boolean remove(Object o) //删除集合中的 o
boolean isEmpty() //检测set是否为空,空返回true,否则返回false
4、应用场景
1、给10W个数据,把这10W个数据中重复的元素删除掉?
存储到Set中。
2、 给10W个数据,找到这10W个数据中第一个重复的数据?
使用Set。看set当中存了没,存了的话返回就行;没存的话进行存储。
3、给10W个数据统计这10W个数据中,每个数据出现的次数?
5、一些oj练习
1、只出现一次的数字 136. 只出现一次的数字 - 力扣(LeetCode)
2、旧键盘 (20)__牛客网 (nowcoder.com)
3、138. 复制带随机指针的链表 - 力扣(LeetCode)
分析:
代码:
6、哈希表
1、引入
构造一种存储结构,通过某种函数使元素的存储位置与它关键码之间能够建立一一映射的关系。则在进行查询时可以通过该函数快速找到改元素。
这种方式称为哈希/散列方法。
->哈希方法中使用的转换函数称为哈希/散列函数,构造出来的结构称为 哈希表/散列表。
举个例子:
2、哈希冲突/哈希碰撞
2-1 避免哈希冲突的方法:
(1)设计合理的哈希函数
常用方法:
->直接定制法
->除留余数法
(2)调节负载因子
负载因子= 元素个数 / 表的容量
负载因子越大,冲突率就越高。
要想降低负载因子,只能增加表的容量。 ----> 扩容
2-2 解决哈希冲突的方法
(1)闭散列/开放定址法
如果当前位置冲突了,就放在冲突位置的下一个。
找下一个位置的方法:->线性探测
弊端:会把冲突的元素放在一起。不好删除【如果删了3,表中不存在该元素了,影响13,23,33,43等冲突的元素】。
->二次探测
让冲突的值更分散。
闭散列/哈希最大的缺陷:空间利用率较低。
(2)开散列/哈希桶/链地址法
原理:把冲突的元素放到一个链表中。
哈希桶的实现:
存储 key value:
通过key值 获取val值: