/** Copyright 2015 Tim Engler, Rareventure LLC This file is part of Tiny Travel Tracker. Tiny Travel Tracker is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Tiny Travel Tracker is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Tiny Travel Tracker. If not, see <http://www.gnu.org/licenses/>. */ package com.rareventure.util; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class MultiDimTree<T extends MultiDimTree.MultiDimLeaf> { public long min, max; //either a tree or a value public MultiDimTree<T> left, right; public MultiDimTree<T> nextDimTree; public T value; public MultiDimTree(long min, long max, MultiDimTree<T> left, MultiDimTree<T> right) { super(); this.min = min; this.max = max; this.left = left; this.right = right; } public MultiDimTree(T value) { super(); this.value = value; } public interface MultiDimLeaf { public long getDim(int dim); } private static class DimensionComparator implements Comparator<MultiDimLeaf> { int dim; public DimensionComparator(int dim) { super(); this.dim = dim; } @Override public int compare(MultiDimLeaf lhs, MultiDimLeaf rhs) { long res = lhs.getDim(dim) - rhs.getDim(dim); if(res < 0) return - 1; else if (res == 0) return 0; return 1; } } public static <R extends MultiDimLeaf> MultiDimTree<R> createTree(R [] items, int totalDimensions) { return createTree(items,0, items.length,new DimensionComparator(0), 0, totalDimensions); } private static <R extends MultiDimLeaf> MultiDimTree<R> createTree(R [] items, int start, int end, DimensionComparator dc, int dim, int totalDimensions) { dc.dim = dim; Arrays.sort(items, start, end, dc); //if there is only one item left if(end == start+1) { return new MultiDimTree<R>(items[start]); } //otherwise there is more than one int mid = (start+end) >> 1; MultiDimTree<R> tree = new MultiDimTree<R>(items[start].getDim(dim), items[end].getDim(dim), createTree(items,start,mid, dc, dim, totalDimensions), createTree(items,mid+1,end, dc, dim, totalDimensions) ); if(dim < totalDimensions-1) { //note that we are creating the next dimension after *all* the tree has been created //in the current dimension. Also, we are creating trees for the next dimension //leaf first. This is done so that the order of the items are preserved for the //current dimension tree.nextDimTree = createTree(items,start, end, dc, dim+1, totalDimensions); } return tree; } }