日升时奋斗,日落时自省

目录

一、Map和Set

1、搜索树的基本概念

2、二叉搜索查找

3、二叉搜索树插入

4、二叉搜索树删除

二、TreeMap

三、TreeSet

一、Map和Set

Map/Set 及实际实现类 HashMap/TreeMap/HashSet/TreeSet 的使用,本次复习TreeMap和TreeSet

Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关:

1.直接遍历,时间复杂度为O(N),元素如果比较多效率会非常慢
2. 二分查找,时间复杂度为O( ),但搜索前必须要求序列是有序的
放入现实中都很难遇到巧合的情况,集合就更针对实现的复杂情况,动态查找集合便是更优的选择Map和Set就是动态查找容器

TreeMap是一个搜索树,但是不仅仅是一颗搜索树,因为单单的搜索树是不能实现很多情况为最优

搜索树相对于TreeMap其他底层代码更简单,初步入手

1、搜索树的基本概念

二叉搜索树也叫二叉排序树,基本性质:
左子树所有节点的值都小于根节点的值;

右子树所有节点的值都大于根节点的值;

它的左右子树都遵循前面的条件,分别也会构成二叉搜索树,这一整棵树才算是二叉搜索树

用一个数据举例:5  3  4  1  7  8  2  6  0  9

2、二叉搜索查找

二叉搜索树的查找有点类似于二分法查找,每次找的数据都会与当前根的值进行比较,大于根节点的就向根的右边进行查找,小于根节点的就向左边进行查找

借上面的图

思路解析:

(1)一颗搜索树不为空情况下

(2)节点值==key,return true;

(3)节点值>key,向左子树找

(4)节点值<key,向右子树找

(5)key在二叉搜索树中不存在,return false

图解:

(1)空树

(2)非空书

static  class  NodeTree{public int val;public NodeTree left;public NodeTree right;public NodeTree(int val){this.val=val;}}public static NodeTree root=null;
public boolean search(int key){NodeTree cur=root;while(cur!=null){   //树不为空if(cur.val>key) {    //节点值>key,向左子树找cur=cur.left;}else if(cur.val<key){   //节点值<key,向右子树找cur=cur.right;}else{return true;    //节点值==key,return true;}}return false;  //没有找到情况}

3、二叉搜索树插入

开始已经知道二叉树是什么了,插入其实就比较简单了

思路:

(1)树为空的情况,直接插入  (树为空)

(2)比根节点小,向左子树走 (树不为空)

(3)比根节点大,向右子树走

(4)如果找到一样的值了,就返回false

(5)直到走到空,就可以插入了

注:找到空了,怎么插入呢,这里就需要一个知道他的父节点,所以这里要记录一个父节点

(1)空树 

 (2)非空树

代码解析:

public  boolean insert(int key){   //二叉搜索树进行插入if(root==null){root=new NodeTree(key);   //如果为空的话就只插入return true;}NodeTree cur=root;NodeTree parent=null;          //这里记录一下父节点,为了后面找到插入位置,进行连接while(cur!=null){               //树不为空,一直找if(cur.val>key){          //跟节点值小的,parent=cur;           //记录当前父节点cur=cur.left;          //找右子树}else if(cur.val<key){     //根节点值大的,parent=cur;            //记录当前父节点cur=cur.right;         //找左子树}else{                 //搜索树中不存在相同的值,如果相同的话就返回falsereturn false;}}NodeTree node=new NodeTree(key);   //找到插入位置了建立新节点if(key> parent.val){           //比父亲节点小,左边插入parent.right=node;}else{                         //比父亲节点大,右边插入parent.left=node;                }return true;}

4、二叉搜索树删除

删除的步骤就相对较多了

思路: 分析以下情况   (设置待删除节点为cur,当前父节点为parent)

(1)cur.left==null

(2)cur.right==null

(3)cur.left!=null&&cur.right!=null

以上三种情况,我们通过图解来详细解释

用替换法将待删除的值替换,并且保证整个二叉搜索树不会动摇

图解:

特殊情况:

代码解析:

代码是与图是相反的可以看着图来推当前代码

public void removeNode(NodeTree parent,NodeTree cur){if(cur.left==null){   //为了找到待删除的值if(cur==root){root=cur.right;}else if(cur==parent.left){parent.left=cur.right;}else if(cur==parent.right){parent.right=cur.right;}}else if(cur.right==null){if(cur==root){root=cur.left;}else if(cur==parent.left){parent.left=cur.left;}else  if(cur==parent.right){parent.right=cur.left;}}else{   //这里我们取一种就可以了NodeTree target=cur.right;NodeTree targetparent=cur;while(target.left!=null) {   //为了找替换值targetparent=target;target=target.left;}cur.val=target.val;if(target==targetparent.left){  //分两种情况targetparent.left=target.right;}else{targetparent.right=target.right;}}}

二、TreeMap

里面是一个集合 ,TreeMap的底层代码是一个Map集合接口

Map底层结构 TreeMap
底层结构 红黑树
插入/删除/查找时间
复杂度
O(1)
是否有序 关于Key有序
线程安全 不安全
插入/删除/查找区别 需要进行元素比较
比较与覆写 key必须能够比较,否则会抛出
ClassCastException异常
应用场景 需要Key有序场景下

 泛型有两个第一个传入key,第二个传入value

这里的key是可以比较的key值,传key时调用了比较器,如果不是可以比较的,就会报错

put方法就是将我们需要的key,value值放入存储起来

getOrDefault方法是key是否找到,如果没有就返回默认值

除了上面的方法,还有以下比较基本的方法使用,可以尝试

方法 解释
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 containsValue(Object value) 判断是否包含 value

前面的图TreeMap用Set棘手后打印

那Map的打印应怎么处理呢

这里肯定不能用foreach,迭代打印因为都没有继承关系

代码解释:

public static void main(String[] args) {Map<String,Integer> map=new TreeMap<>();map.put("hello",2);map.put("abc",1);Set<Map.Entry<String,Integer>> entries=map.entrySet();for (Map.Entry<String,Integer> set:entries) {System.out.println(set.getKey()+" "+set.getValue());}}

图解一下:

三、TreeSet

TreeSet的底层是TreeMap,去掉重复的元素,key的重复不会再搜索树中出现

TreeSet继承了Set,Set又继承了Collection

注:将Map与Set联系起来Set<Map.Entry<String,Integer>> entries=map.entrySet();

才能使用Iterable中迭代打印,foreach打印等方法,Map一系中是独立出来并没有实现在下面的关系图中,TreeSet弥补了当前的缺陷。

TreeSet的底层是TreeMap,直接将TreeMap与上面的关系图联系起来,TreeSet也同样有TreeMap的限制,泛型传值中是需要经过比较。(用于Map相同的方法)

Set<Map.Entry<String,Integer>> entries=map.entrySet();

解释:

TreeMap与TreeSet(初步了解)相关推荐

  1. Treemap and Treeset java 实现

    引自:  http://www.ibm.com/developerworks/cn/java/j-lo-tree/(红黑树部分 详见这里) 对于 TreeMap 而言,它采用一种被称为"红黑 ...

  2. 小汤学编程之JAVA基础day11——集合框架:List/Set/Map集合、Collections集合工具类、泛型、TreeMap和TreeSet

    一.集合的特点 二.继承结构图 三.List集合 1.特点     2.ArrayList类     3.LinkedList类     4.两者的对比     5.集合的遍历 四.Set集合 1.特 ...

  3. HashMap,HashTable,TreeMap,HashSet,TreeSet

    注意:最好先看一下(三)中 树红黑树的数据结构分析,可以的话数组,链表的数据结构也先复习一下,这里默认你懂数组,链表 2.2 map Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对 ...

  4. java学习:容器排序:TreeMap和TreeSet实现自定义排序的使用方法?两者的区别?

    文章目录 TreeMap和TreeSet实现自定义排序的实现 1.TreeMap实现自定义排序 (1)构造函数中new Comparator,匿名内部类,重写compare 方法. (2)实体类实现C ...

  5. Java TreeMap 和 TreeSet 源码解析

    A Red-Black tree based {@link NavigableMap} implementation. The map is sorted according to the {@lin ...

  6. Java中TreeMap和TreeSet的底层实现

    TreeSet底层则采用NavigableMap这个接口来保存TreeSet集合,而实际上NavigableMap只是一个接口,实际上TreeSet还是用TreeMap来保存set元素. TreeSe ...

  7. 线程安全的HashMap,TreeMap,ArrayList,TreeSet,Set

    1.线程安全的集合:集合类中,用于实现线程安全的有两种办法,一种是使用Collections.synchronizedList来替代ArrayList 具体的API如下图: 但是该类会出现并发异常:代 ...

  8. TreeMap、TreeSet简介

    TreeMap TreeMap底层采用红黑树保存每个Entry对象,红黑树是一种自平衡排序二叉树. TreeMap添加元素源码: public V put(K key, V value) {// 获取 ...

  9. TreeMap和TreeSet

    TreeMap是最近遇到的,它可以根据key值自动排序,默认状态是对key进行递增排序,也可以自定义 treemap的存放顺序和实际位置并不相同,算是无序集合 treemap的常用 方法在下面 (转载 ...

最新文章

  1. ASP.Net定时任务执行
  2. 五分钟了解Mysql的行级锁——《深究Mysql锁》
  3. php ci post 请求,ci检测是ajax还是页面post提交数据的方法
  4. Windows 10重装系统时,提示Windows只能安装到GPT磁盘的解决方法(更新于2021.4.28)
  5. 离散数学知识点总结-命题逻辑
  6. 循迹传感器(TCRT5000)的介绍以及使用(STM32)
  7. tensorflow 版本列表_最新|谷歌发布TensorFlow 1.3.0版本,都更新了哪些内容?
  8. 从零开始刷Leetcode——数组(31.33)
  9. 华为NP课程笔记16-MPLS(上)
  10. 步进电机的计算机控制系统设计,步进电机控制系统的设计与实现
  11. 解决Redis持久化数据丢失
  12. python一只青蛙一次可以_Python面试题系列之11 变态青蛙跳
  13. CSS hover改变背景图片过渡动画生硬
  14. 金融行业文档加密方案
  15. 影视短视频剪辑的完整操作流程(普通人也能学会)
  16. 如何做好基层管理者(一)
  17. Android Scroller的使用
  18. 软件设计模式——单例模式
  19. 如何搭建在线网校最省钱
  20. win7系统安装信息服务器不可用怎么办,Win7系统RPC服务器不可用怎么办?

热门文章

  1. java 反编译软件
  2. NLP顶会近三年小众研究领域
  3. 在jsp中引入jQuery
  4. python使用nltk进行中文语料库的词频分布统计
  5. 异次元店铺 - 最适合你的个人店铺系统源码(原荔枝发卡)
  6. 分享一款电机控制国产32位单片机MM32SPIN360C
  7. Commvault发布横向扩展一体机 矛头对准Rubrik和Cohesity
  8. PHP编程54条必知
  9. 曾有一个人,爱我如生命(2)
  10. DSP-FTU实现DNP3.0