关于Set接口中TreeSet实现类、Map接口和HashMap实现类、数据结构、自然排序(比较器)和自定义排序(指定比较器)的课程笔记

TreeSet©

(1).底层数据结构:二叉树
(2).父接口: SortedSet(I),可排序的集合
(3).特点:
a.TreeSet是可排序的,最常用的中序遍历
(4).TreeSet的存储过程
a.最开始和根节点进行比较 - 通过compareTo()进行比较
b.如果比根大,则存储在右边
c.如果比根小,则存储在左边
d.如果和根一样大,则不存入

递归方式写add方法
//定义一个内部方法
private  void  addNode(Node node , T t){
   if(((Comparable)t).compareTo(node.data)>0){
       if(node.right == null){//如果下个节点为空
           node.right = new Node(t);//新建节点 存入t
           return;
       }
       addNode(node.right,t);
   }else if(((Comparable)t).compareTo(node.data)<0){
       if(node.lift == null){
           node.lift = new Node(t);
           return;
       }
       addNode(node.lift,t);
   }
   }

//递归方式
public void add(T t){
    //判断根节点是否为空
    if(root == null){
        root = new Node<T>(t);
        return;
    }
    addNode(root , t);
}

数据结构:

数组 链表 栈 队列 二叉树

1.顺序结构 - 可扩容的数组

1)底层实现: 数组
2)特点:
a.按照顺序排列,每个元素都带有标号
b.除了有标号是连续的,内存中的物理空间也是连续的

3)优缺点:
优点: 查询速度快(因为有连续的下标,可以根据下标进行查询)
缺点:
a.插入/删除速度慢(插入/删除都是要移动元素的,所以元素一多就会执行效率慢)
b.内存的物理空间是连续的,利用不到碎片空间

2.链式结构

1)底层实现:节点(data(存储数据) + next(下一个节点的引用))
2)特点:
a.链表是内存中固定顺序,但是他的物理空间不连续
b.没有下标,并且从头节点开始
c.所有节点的访问,都必须通过头节点
d.head(头节点): 只存next,不存data
e.head.next = null -> 空链表
3)不同的链表:
a.单向链表
特点: 只有头节点,只能从头节点出发
b.双向链表(最常用)
特点: 有头节点和尾节点,所以可以从头节点出发也可以从尾节点出发
头节点: 不存元素,只有next
尾节点: 不存元素,只有pre

​ c.循环链表
​ 特点: 尾节点指向头节点
​ 可以从任意位置开始,都可以找到想要的元素

4)优缺点:
优点:
a.插入/删除效率高
b.不需要连续的内存物理空间,所以空间利用率高
缺点:
查询效率低,只能从头节点出发开始查询

3.栈

​ 1).底层实现: 可以基于链表或数组
​ 2).特点: 先进后出(后进先出)
​ 3).特有方法:
​ push() - 压栈(往里加)
​ pop() - 弹栈(往外取)

4.队列

1).底层实现: 以基于链表或数组
2).特点: 先进先出(后进后出)

线性结构: 数据元素之间存在一对一的关系
顺序结构 + 链式结构 + 队列 + 栈 -> 线性结构

5.二叉树

1).树的基本概念:
一种表示层次关系的(一对多)的数据结构.
a.有且只有一个特定的节点(结点),该节点没有前驱,被称为根节点.
b.剩余的n个互不相交的子集,其中每个子集也都是一棵树,被称为根节点的子树

2).树的表示方式:
倒悬树,嵌套法,凹凸法

3).二叉树
a.普通树可以很方便的转变成二叉树,二叉树的节点数量最多为2
b.二叉树是n个有限元素的集合,由一个称为根(root)的元素
以及两个不想交的,被分别称为左子树/右子树,组成有序树.
c.当集合为空时,就称之为空二叉树.

4).满二叉树:
二叉树的第i层最多有2^(i-1)个节点
每层的节点数都是2^(i-1),这种叫做满二叉树

5).完全二叉树:
对树中的节点,从上至下,从左至右的顺序进行编号,如果编号为i(1≤i≤n)的节点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵树称之为完成二叉树.

6).排序二叉树
定义一:
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。

7).平衡二叉树
a.前提必须是有序的二叉树,它的左右子树的高度差不超过(≤)1,
他的所有子树也要满足这个要求.
b.如果有一个有序二叉树呈单支状,它的效率就接近于链表,因此只有达到平衡时它的效率才是最高.

8)二叉树的遍历:
先序遍历 - 根左右
中序遍历 - 左根右
后序遍历 - 左右根

​ 先序/后序遍历,可以确定根的位置
​ 根据中序遍历找出左右子树的具体位置

Map

1.特点:
1).Map集合是一个双列集合,是以key-value的形式表示.
2)key和value都可以使用泛型,也就意味着可以使用引用数据类型(自定义类)
3).key值都不允许有重复值
4).value值允许有多个重复值
5).如果key值完全一致,则value值会被覆盖
6).因为key是唯一的,可以通过key找到value值

2.Map接口的结构:
Map(I)
|- HashMap©
|- LinkedHashMap©
|- HashTable©
|- ConcurrentHashMap©
|- SortedMap(I)
|- TreeMap©

HashMap©:

1.底层实现: 哈希表(散列表)
2.底层数据结构:
JDK1.7: 数组 + 双向链表
JDK1.8: 数组 + 双向链表 + 红黑树
3.特点:
就是Map接口的特点

4.HashMap的存储过程:
a.计算key的hashCode值,确定位置
b.如果位置上有元素,则使用equals()和该位置上的所有元素比较
c.如果元素一致,会进行覆盖
d.如果元素不一致,则直接存入链表末尾

5.初始空间大小
a.默认初始容量:16
b.加载因子: 0.75 -> 容量达到百分之75的时候进行扩容
b.如果元素太少就进行扩容,会造成空间的浪费
c.如果元素太多进行扩容,则会造成效率低下

在这里插入图片描述

 HashMap<String, String> map = new HashMap<>();

/*
// V  put (k,v);
 存储键值对的时候,key重复
         会使用新的value替换map中重复key的value
         返回被替换的value值
  */
 String v1 = map.put("小乔", "周瑜");
 System.out.println(v1);//null
 String v2 = map.put("小乔", "曹操");
 System.out.println(v2);//周瑜

 map.put("大乔","孙策");
 map.put("孙尚香","刘备");

 //  1.hashmap 是无序的,按照key的hashcode()进行排序
 System.out.println(map);//{大乔=孙策, 孙尚香=刘备, 小乔=周瑜}

 /*
         key不允许有重复值   key允许有且只有一个null值
         value允许有重复值   value允许有多个null值
  */
 map.put("孙尚香","刘禅");
 map.put("大乔","曹操");
 System.out.println(map);//{大乔=曹操, 孙尚香=刘禅, 小乔=曹操}

自然排序(比较器)和自定义排序(指定比较器):

1.自然排序 - Comparable(I)

1).使用步骤
a.在实体类中实现Comparable接口
b.重写Comparable中的compareTo()

2).比较规则:
a. this 和 obj必须是同一种类型
b. this 比 obj 小, 返回负数
this 比 obj 大, 返回正数
this 和 obj 一样大, 返回0,则不存入
c.正序和倒序
正序: this在前,obj在后 -> 前比后
倒序: obj在前,this在后 -> 后比前

2.自定义排序 - Comparator(I)

1).使用步骤:
a.使用匿名内部类方式实现Comparator接口
b.重写Comparator接口中的compare()
2).比较规则
a.比较的是传进来的两个对象
b.compare()返回0的时候,表示所有对象都一样,默认按照原本顺序排序.
c.正序和倒序
正序: 前比后
倒序: 后比前

3.java当中的排序方法:

1.数组
Arrays.sort(arr) -> 自然排序
Arrays.sort(arr,new Comparator) -> 自定义排序
2.List
Collections.sort(list) ->自然排序
Collections.sort(list,new Comparator) ->自定义排序
存在ArrayList中的sort,没有重载
list.sort(new Comparator) ->自定义排序
3.Set
new TreeSet() -> 自然排序
new TreeSet(new Comparator) -> 自定义排序

4.Map
new TreeMap() ->自然排序
new TreeMap(new Comparator)-> 自定义排序

 ArrayList<Integer> list = new ArrayList<>();
        list.add(23);
        list.add(45);
        list.add(12);
        list.add(3);
        list.add(89);
        list.add(65);

        System.out.println(list);
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });
        System.out.println(list);

        
        //Collections.sort(list);//默认排序
        //System.out.println(list);

        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //return 0;//不排序
                //return o1-o2;//正序
                return o2-o1;//倒序
            }
        });

        System.out.println(list);

        System.out.println("--------------");

        
        Integer[] arr = {12,67,43,89,34,32};
        System.out.println(Arrays.toString(arr));
       // Arrays.sort(arr);//默认排序
        //System.out.println(Arrays.toString(arr));
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //return 0;//不排序
                //return o1-o2;//正序
                return o2-o1;//倒序
            }
        });
        System.out.println(Arrays.toString(arr));

        
        System.out.println("----------------------");
        
        
        Integer[] arr1 = {12,67,43,89,34,32,1,6,4,7,9,99};
        Arrays.sort(arr1, 2, 8, new Comparator<Integer>() {
            @Override//对指定数组中指定的范围 进行排序
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });
        System.out.println(Arrays.toString(arr1));
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值