3

Java知识点总结(Java容器-TreeSet)

@(Java知识点总结)[Java, Java容器, JavaCollection, JavaSet]

TreeSet

TreeSet是SortedSet接口的唯一实现,TreeSet可以确保集合元素处于排序状态,底层是一棵排序树。

  1. 底层使用红黑树算法进行维护,因此性能相对于HashSet来说要差一些,因为内部会自动进行排序操作。
  2. TreeSet也是线程不安全
  3. 排序分为自然排序,定制排序,自然排序是TreeSet内部对add进来的值进行排序,定制排序是对排序条件的限制

手动实现TreeSet

package mySet;  
  
import java.util.Comparator;  
import java.util.Iterator;  
import java.util.NoSuchElementException;  
  
/** 
 * 实现一个简单的TreeSet 
 * @author george 
 */  
public class MyTreeSet<E> implements Cloneable, java.io.Serializable {  
    // 为set底层树的结构排序用的比较器 当按照E的自然排序时为null  
    private final Comparator<? super E> comparator;  
    // 头节点  
    private transient SetNode<E> root = null;  
    // 节点个数  
    private transient int size = 0;  
  
    /** 
     * 无参构造,设置比较器为null 
     */  
    public MyTreeSet() {  
        comparator = null;  
    }  
  
    /** 
     * 构造函数,传入定义好的比较器对象 
     *  
     * @param comparator 
     *            :比较器对象 
     */  
    public MyTreeSet(Comparator<? super E> comparator) {  
        this.comparator = comparator;  
    }  
  
    /** 
     * 插入对象e到MyTreeSet中 
     *  
     * @param e 
     *            :要插入的对象 
     * @return:返回是否插入成功 
     */  
    public boolean add(E e) {  
        SetNode<E> n = root;  
        if (n == null) {  
            root = new SetNode<E>(e, null);  
            size = 1;  
            return true;  
        }  
        int comp;  
        SetNode<E> parents;  
        Comparator<? super E> cptor = comparator;  
        // 若比较器不为空 用Comparator进行比较  
        if (cptor != null) {  
            do {  
                parents = n;  
                comp = cptor.compare(e, n.e);  
                if (comp < 0)  
                    n = n.left;  
                else if (comp > 0)  
                    n = n.right;  
                else {  
                    return false;  
                }  
            } while (n != null);  
        } else {  
            if (e == null)  
                throw new NullPointerException();  
            // 用定义好的自然顺序方法进行排序比较  
            Comparable<? super E> cpb = (Comparable<? super E>) e;  
            do {  
                parents = n;  
                comp = cpb.compareTo(n.e);  
                if (comp < 0)  
                    n = n.left;  
                else if (comp > 0)  
                    n = n.right;  
                else {  
                    return false;  
                }  
            } while (n != null);  
        }  
        // 找到新元素将来位置的父结点后,将元素实例化成结点插入到树中  
        SetNode<E> newNode = new SetNode<E>(e, parents);  
        if (comp < 0)  
            parents.left = newNode;  
        else  
            parents.right = newNode;  
        size++;  
        return true;  
    }  
  
    /** 
     * 返回是否含有元素e 
     *  
     * @param e 
     * @return 
     */  
    public boolean contains(E e) {  
        return getNode(e) != null;  
    }  
  
    /** 
     * 删除元素e所在的结点 
     *  
     * @param e 
     * @return 
     */  
    public boolean remove(E e) {  
        SetNode<E> node = getNode(e);// 找到元素e所在节点  
        if (node == null)  
            return false;  
        deleteNode(node);// 进行删除  
        return true;  
    }  
  
    /** 
     * 找到元素e在树中的结点 
     *  
     * @param e 
     * @return 
     */  
    private SetNode<E> getNode(E e) {  
        SetNode<E> n = root;  
        int comp;  
        SetNode<E> parents;  
        Comparator<? super E> cptor = comparator;  
        // 若比较器不为空 用Comparator进行比较  
        if (cptor != null) {  
            do {  
                parents = n;  
                comp = cptor.compare(e, n.e);  
                if (comp < 0)  
                    n = n.left;  
                else if (comp > 0)  
                    n = n.right;  
                else {  
                    return parents;  
                }  
            } while (n != null);  
        } else {  
            if (e == null)  
                throw new NullPointerException();  
            // 用定义好的自然顺序方法进行排序比较  
            Comparable<? super E> cpb = (Comparable<? super E>) e;  
            do {  
                parents = n;  
                comp = cpb.compareTo(n.e);  
                if (comp < 0)  
                    n = n.left;  
                else if (comp > 0)  
                    n = n.right;  
                else {  
                    return parents;  
                }  
            } while (n != null);  
        }  
        return null;  
    }  
  
    /** 
     * 删除树中的节点node 当结点node有左右子女时,往下所搜与node中的元素最为接近的元素的结点 
     * 找到后将该结点的元素值赋给node,让node指向该结点, 接下来删除这个结点。 注意:最后要去掉的节点的子女个数都是小于2的 
     *  
     * @param node 
     */  
    void deleteNode(SetNode<E> node) {  
        size--;  
        SetNode<E> rep;  
        if (node.left != null && node.right != null) {  
            rep = replaceNode(node);  
            node.e = rep.e;  
            node = rep;  
        }  
        rep = (node.left != null ? node.left : node.right);  
  
        if (rep != null) {  
            rep.parents = node.parents;  
            if (node.parents == null)  
                root = rep;  
            else if (node == node.parents.left)  
                node.parents.left = rep;  
            else if (node == node.parents.right)  
                node.parents.right = rep;  
        } else {  
            if (node.parents == null) {  
                root = null;  
            }  
            if (node.parents != null) {  
                if (node == node.parents.left)  
                    node.parents.left = null;  
                else if (node == node.parents.right)  
                    node.parents.right = null;  
            }  
        }  
    }  
  
    /** 
     * 找到距离node中的元素大小最近的结点 
     *  
     * @param node 
     * @return 
     */  
    SetNode<E> replaceNode(SetNode<E> node) {  
        if (node == null)  
            return null;  
        else if (node.right != null) {  
            SetNode<E> p = node.right;  
            while (p.left != null)  
                p = p.left;  
            return p;  
        } else {  
            SetNode<E> p = node.parents;  
            SetNode<E> ch = node;  
            while (p != null && ch == p.right) {  
                ch = p;  
                p = p.parents;  
            }  
            return p;  
        }  
    }  
  
    /** 
     * 清空set集合 
     */  
    public void clear() {  
        size = 0;  
        root = null;  
    }  
  
    /** 
     * 返回结点的个数 
     *  
     * @return 
     */  
    public int size() {  
        return size;  
    }  
  
    /** 
     * 找到最小的元素 
     *  
     * @return 
     */  
    public E first() {  
        SetNode<E> p = root;  
        if (p != null)  
            while (p.left != null)  
                p = p.left;  
        if (p.e == null)  
            throw new NoSuchElementException();  
        else  
            return p.e;  
    }  
  
    /** 
     * 找到最大的元素 
     *  
     * @return 
     */  
    public E last() {  
        SetNode<E> p = root;  
        if (p != null)  
            while (p.right != null)  
                p = p.right;  
        if (p.e == null)  
            throw new NoSuchElementException();  
        else  
            return p.e;  
    }  
  
    /** 
     * 找到最小的元素所在的结点 
     *  
     * @return 
     */  
    public SetNode<E> firstNode() {  
        SetNode<E> p = root;  
        if (p != null)  
            while (p.left != null)  
                p = p.left;  
        if (p.e == null)  
            throw new NoSuchElementException();  
        else  
            return p;  
    }  
  
    /** 
     * 迭代器 
     * @return 
     */  
    public Iterator<E> iterator() {  
        return new KeyIterator(firstNode(), this);  
    }  
}  

苏生
803 声望725 粉丝