A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘忠德 黑马帝   /  2012-1-1 15:42  /  3501 人查看  /  4 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘忠德 于 2012-1-2 10:18 编辑

RT,TreeSet和TreeMap是怎么样实现排序的呢?

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

4 个回复

倒序浏览
TreeSet类内部使用了一个TreeMap对象。其中使用了二叉排序树的结构。

插入新节点的方法如下:
    public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {  //如果不存在根节点则创建一个
            root = new Entry<K,V>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {   //判断有没有比较器。
            do {                    //从根开始向下查找插入的位置(直到叶节点)
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<K,V>(key, value, parent);  //插入新节点。
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

评分

参与人数 1技术分 +1 收起 理由
王德云 + 1

查看全部评分

回复 使用道具 举报
注意的是它们不在使用哈希表,存储方式是一个特殊的二叉树,既然是有序的,自然要求元素是可以比较大小的,如果构造函数指定Comparator的话,就使用这个Comparator比较大小,如果没有指定Comparator的话,就使用自然排序(元素要实现Comparable接口).如果这两个都不可用,就会出错的.
回复 使用道具 举报
哈希表HashMap,红黑树TreeMap,链表LinkedList,动态数组ArrayList等数据结构的迭代。

既然TreeMap是有序的,自然要求元素是可以比较大小的,如果构造函数指定Comparator的话,就使用这个Comparator比较大小,如果没有指定Comparator的话,就使用自然排序(元素要实现Comparable接口).如果这两个都不可用,就等着出错吧.
有关Java的排序:http://blog.csdn.net/treeroot/archive/2004/10/19/142636.aspx

因为是二叉树,所以一般查找时间复杂度为 o(lg(n)),这个效率当然没有HashMap的效率高.不过TreeMap比HashMap功能强大,如果不需要排序的话当然不会用TreeMap,如果需要排序的话,HashMap无法胜任,当然要用TreeMap了,它可以求子Map.所以这个是适用场合问题,无法比较他们.

另外,我们习惯了,有Map就会跟一个Set,我们都可以猜到TreeSet和通过TreeMap实现的一个SortedSet的实现.不过我觉的TreeSet好像比TreeMap用的场合多一些,求子集是很常用的呀!!

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
谢谢楼上 的解答,了解了~~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马