如何查找TreeSet的根元素

时间:2017-11-09 18:03:00

标签: java data-structures

我有一个树集。如何找到树集的根元素:

TreeSet<Integer> ts = new TreeSet<Integer>();
    ts.add(8);
    ts.add(3);
    ts.add(8);
    ts.add(1);
    ts.add(0);
    ts.add(4);
    ts.add(7);

如果我们采用下面的树集,20是根元素: TreeSet

1 个答案:

答案 0 :(得分:2)

如果你绝对需要(欲望?)知道当前的根值是什么,你可以使用反射。

注意: TreeSetTreeMap的内部实施可能会发生变化,以下代码将失败。代码已经过JDK 1.8u91测试 此外,如果存在安全管理器,代码将失败并显示SecurityException

以下两种辅助方法可用于为您提供TreeSetTreeMap的根。

@SuppressWarnings("unchecked")
public static <E> E getTreeRoot(TreeSet<E> ts) {
    try {
        Field mField = TreeSet.class.getDeclaredField("m");
        mField.setAccessible(true);
        return getTreeRoot((TreeMap<E, Object>) mField.get(ts));
    } catch (NoSuchFieldException | IllegalAccessException e) {
        throw new IllegalStateException("Internals of TreeSet has changed", e);
    }
}

@SuppressWarnings("unchecked")
public static <K,V> K getTreeRoot(TreeMap<K,V> tm) {
    try {
        Field rootField = TreeMap.class.getDeclaredField("root");
        rootField.setAccessible(true);
        Map.Entry<K,V> root = (Map.Entry<K,V>) rootField.get(tm);
        return (root == null ? null : root.getKey());
    } catch (NoSuchFieldException | IllegalAccessException e) {
        throw new IllegalStateException("Internals of TreeMap has changed", e);
    }
}

测试助手

private static void test(int... values) {
    TreeSet<Integer> ts = new TreeSet<>();
    System.out.println("Root is " + getTreeRoot(ts) + " for " + ts);
    for (int v : values) {
        ts.add(v);
        System.out.println("Root is " + getTreeRoot(ts) + " for " + ts);
    }
}

测试1 (有问题的值)

test(8, 3, 8, 1, 0, 4, 7);
Root is null for []
Root is 8 for [8]
Root is 8 for [3, 8]
Root is 8 for [3, 8]
Root is 3 for [1, 3, 8]
Root is 3 for [0, 1, 3, 8]
Root is 3 for [0, 1, 3, 4, 8]
Root is 3 for [0, 1, 3, 4, 7, 8]

测试2 升序顺序中的图表中的值)

test(5, 15, 17, 18, 20, 22, 25, 27, 30);
Root is null for []
Root is 5 for [5]
Root is 5 for [5, 15]
Root is 15 for [5, 15, 17]
Root is 15 for [5, 15, 17, 18]
Root is 15 for [5, 15, 17, 18, 20]
Root is 15 for [5, 15, 17, 18, 20, 22]
Root is 15 for [5, 15, 17, 18, 20, 22, 25]
Root is 18 for [5, 15, 17, 18, 20, 22, 25, 27]
Root is 18 for [5, 15, 17, 18, 20, 22, 25, 27, 30]

测试3 (图表中降序顺序中的值)

test(30, 27, 25, 22, 20, 18, 17, 15, 5);
Root is null for []
Root is 30 for [30]
Root is 30 for [27, 30]
Root is 27 for [25, 27, 30]
Root is 27 for [22, 25, 27, 30]
Root is 27 for [20, 22, 25, 27, 30]
Root is 27 for [18, 20, 22, 25, 27, 30]
Root is 27 for [17, 18, 20, 22, 25, 27, 30]
Root is 22 for [15, 17, 18, 20, 22, 25, 27, 30]
Root is 22 for [5, 15, 17, 18, 20, 22, 25, 27, 30]

如您所见,根取决于插入的顺序。