Set接口、二叉排序树、常用工具类

目录

二叉排序树

二叉排序树的插入

二叉排序树的查找

 二叉排序树的删除

Set接口

HashSet集合

常用方法

TreeSet集合

总结

Collections工具类


二叉排序树

左节点的值小于根节点,右节点的值大于根节点,并且每一个子树都是二叉排序树

二叉排序树的插入

值小于根节点,在左子树进行插入,值大于根节点,在右子树进行插入

    public static Node insert(Node head, int value) {
        if (head == null) {
            return new Node(value);
        }
        if (value < head.value) {//值比当前根的结点小
            head.left = insert(head.left, value);
        } else if (value > head.value)
            head.right = insert(head.right, value);
        return head;
    }

二叉排序树的查找

值小于根节点,在左子树进行查找,值大于根节点,在右子树进行查找

    public static boolean search(Node head, int value) {
        if (head == null)
            return false;
        if (head.value == value)
            return true;
        if (head.value < value) {
            return search(head.right, value);
        } else {
            return search(head.left, value);
        }
    }

 二叉排序树的删除

    public static Node remove(Node head, int value) {
        Node parent = head;
        Node cur = head;
        while (cur != null) {
            if (cur.value == value) {//cur是删除结点
                if (cur.left == null) {
                    if (cur == head) {
                        head = head.right;
                        return head;
                    }
                    if (cur == parent.left) {
                        parent.left = cur.right;
                        return head;
                    }
                    if (cur == parent.right) {
                        parent.right = cur.right;
                        return head;
                    }
                } else if (cur.right == null) {
                    if (cur == head) {
                        head = head.left;
                        return head;
                    }
                    if (cur == parent.left) {
                        parent.left = cur.left;
                        return head;
                    }
                    if (cur == parent.right) {
                        parent.right = cur.left;
                        return head;
                    }
                } else {
                    Node min = cur.right;
                    if (min.left == null) {//如果左子树为空,最小的结点就是min
                        cur.value = min.value;
                        cur.right = min.right;
                        return head;
                    }
                    while (min.left != null) {
                        parent = min;
                        min = min.left;
                    }
                    cur.value = min.value;
                    parent.left = null;
                    return head;
                }
            }
            if (value > cur.value) {
                parent = cur;
                cur = cur.right;
            } else {
                parent = cur;
                cur = cur.left;
            }
        }
        return null;
    }

Set接口

Set接口和List接口同样继承于Collection集合,Set集合的元素无序且不重复

HashSet集合

HashSet集合是Set接口的实现类,内部是一个哈希表

常用方法

1、插入元素

1、根据hashCode()得到对应的hash值

2、根据hash值找到数组的对应存储位置

3、判断对应位置有没有元素:没有元素就插入当前元素;有元素就比较是否和当前对象的value值相等,相等就不插入,不相等就插入

模拟实现

public class MyHashSet<E> {
    static class Node<E> {
        int hash;
        E value;
        Node<E> next;

        public Node(E value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    '}';
        }
    }
    private final float load = 0.75f;
    private int count = 0;
    Node<E>[] table =  new Node[10];
    public void add(E value) {
        //1、生成hash值
        int hash =value.hashCode() % table.length;
//获取hash值对应的数组位置
        Node<E> cur = table[hash];
        //插入结点 jdk1.8使用尾插,我们使用头插
        if (cur == null) {
            table[hash] = new Node<>(value);
            count++;
            resize();
            return;
        }
        while (cur != null) {
            if (cur.value.equals(value)) {//如果元素之前已经存在,不插入
                return;
            }
            cur = cur.next;
        }
        //元素可以插入
        Node<E> newnode = new Node<>(value);
        newnode.next = table[hash];
        table[hash] = newnode;
        count++;
        //计算负载因子,调整数组长度
        resize();
    }
  private void   resize(){
        if(count*1.0/table.length>load){//需要调整数组长度
            Node<E>[] newtable =  new Node[table.length*2];
            for (int i = 0; i < table.length; i++) {
                Node<E> cur = table[i];
                while (cur != null) {
                    //1、生成hash值
                    int hash = cur.value.hashCode() % newtable.length;
                    //2、重新插入结点
                    Node<E> curNext = cur.next;
                    cur.next = newtable[hash];
                    newtable[hash] = cur;
                    cur = curNext;
                }
            }
            table=newtable;
            }
        }
        public void print(){
            for (int i = 0; i < table.length; i++) {
                Node<E> cur = table[i];
                while (cur != null) {
                    System.out.println(cur);
                    cur=cur.next;
                }
            }
        }
}
class Person{
    int gae;
    String name;

    public Person(int gae, String name) {
        this.gae = gae;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "gae=" + gae +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return gae == person.gae && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(gae, name);
    }
}
public class TextDemo {
    public static void main3(String[] args) {
        MyHashSet<Person> myHashSet=new MyHashSet<>();
        myHashSet.add(new Person(1,"李四"));
        myHashSet.add(new Person(9,"李四"));
        myHashSet.add(new Person(10,"李四"));
        myHashSet.add(new Person(1,"李四"));
        myHashSet.add(new Person(10,"李四"));
        myHashSet.print();
    }

TreeSet集合

HashSet集合内部使用二叉排序树来存储元素,可以保证没有重复元素

 public static void main(String[] args) {
        Set<Integer>set=new TreeSet<>();
        set.add(1);
        set.add(3);
        set.add(1);
        System.out.println(set);
        set.remove(1);
        System.out.println(set);
    }

总结

1、HashSet可以插入null,TreeSet不可以插入null

 2、HashSet和TreeSet的区别

HashSet集合内部是一个哈希表,TreeSet集合内部是一个二叉排序树

TreeSet插入查找的时间复杂度O(log2 N)

HashSet插入查找的时间复杂度O(1)

Collections工具类

集合:集合分为单列集合和双列集合

单列集合Collection:List接口存放的元素:有序且可重复,Set接口存放的元素:无需且不可重复

双列集合Map:存储key-value的键值对

Collections工具类提供了一系列对集合的操作方法

反转---reverse()

 public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(1);
        list.add(3);
        System.out.println(list);
        Collections.reverse(list);
        System.out.println(list);

    }

addAll()---将所有元素插入集合

 public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        Collections.addAll(list,1,3,2,4,5);
        System.out.println(list);
    }

sort()---对集合的元素进行排序

   public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(3);
        list.add(1);
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    }

swap()---交换集合内两个下标的元素

    public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(3);
        list.add(1);
        System.out.println(list);
        Collections.swap(list,0,1);
        System.out.println(list);
    }

返回最值max(),min()

  public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(3);
        list.add(1);
        System.out.println(list);
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
    }

 shuffle()---打乱元素顺序

    public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(3);
        list.add(1);
        list.add(1);
        Collections.shuffle(list);
        System.out.println(list);
    }

 replaceAll()---使用新的值替换全部旧的元素值

    public static void main(String[] args) {
        List<Integer>list=new ArrayList<>() ;
        list.add(3);
        list.add(1);
        list.add(1);
        Collections.replaceAll(list,1,9);
        System.out.println(list);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值