Skip to content
Snippets Groups Projects
Commit d1135393 authored by Haley Glavina's avatar Haley Glavina
Browse files

RBTree object implementation

parents ca56cee4 5e0b31d5
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sandbox</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
package biotree;
import sort.KDT;
public class Data {
KDT data = new KDT<Integer>();
public static void initialize(Record rec) {
}
}
package sandbox;
public class Point implements Comparable<Point> {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public String toString() {
return String.format("(%d,%d)", x, y);
}
@Override
public int compareTo(Point o) {
// TODO Auto-generated method stub
return 0;
}
}
package search;
import java.util.Iterator;
public class Fish<Integer> implements Iterable<Integer> {
@Override
public Iterator<Integer> iterator() {
// TODO Auto-generated method stub
return null;
}
}
package search;
public class GraphBuild {
private final int V;
private int E;
private Fish<Integer>[] adj;
public GraphBuild(int V){
this.V = V;
this.E = 0;
adj = (Fish<Integer>[]) new Fish[V];
for(int v = 0; v < V; v++)
adj[v] = new Fish<Integer>();
}
/*public GraphBuild(In in){
}*/
}
package sort;
public enum Bound {
LOWER, UPPER, LOWHIGH, ANY;
}
package sort;
public interface GeneralCompare<T> {
/**
* Compare two Comparable elements based on an arbitrary ordering definition.
* @param a1 The first value to be compared.
* @param a2 The second value to be compared
* @return Integer < 0 if a1 is less than a2, 0 if equal and > 0 if a1 is bigger than a2
*/
public int compare(Comparable<T> a1, Comparable<T> a2);
}
package sort;
public interface GeneralRange<T extends Comparable<T>> {
/**
* Compare two Comparable elements based on an arbitrary ordering definition.
* @param a1 The first value to be compared.
* @param a2 The second value to be compared
* @return Integer < 0 if a1 is less than a2, 0 if equal and > 0 if a1 is bigger than a2
*/
public int isInBounds(T a1);
}
package sort;
import sandbox.Point;
import java.util.ArrayList;
public class KDT<KeyVal extends Comparable<KeyVal>> {
Node root;
ArrayList<GeneralCompare<KeyVal>> axes;
public static void main(String[] args) {
GeneralCompare<Point> compX = (p1, p2) -> ((Point) p1).getX() - ((Point) p2).getX();
GeneralCompare<Point> compY = (p1, p2) -> ((Point) p1).getY() - ((Point) p2).getY();
//(2,3), (4,7), (5,4), (7,2), (8,1), (9,6)
//(8,1), (7,2), (2,3), (5,4), (9,6), (4,7)
Point p1 = new Point(2,3);
Point p2 = new Point(5,4);
Point p3 = new Point(9,6);
Point p4 = new Point(4,7);
Point p5 = new Point(8,1);
Point p6 = new Point(7,2);
ArrayList<GeneralCompare<Point>> axes = new ArrayList<GeneralCompare<Point>>();
axes.add(compX);
axes.add(compY);
Point[] pts = {p1, p2, p3, p4, p5, p6};
KDT<Point> kdt = new KDT<Point>(axes, pts);
System.out.println(kdt.size());
System.out.println(kdt.height());
//GeneralRange<Point> xRange = p -> 4 <= p.getX() && p.getX() <= 6;
//GeneralRange<Point> yRange = p -> 3 <= p.getY() && p.getY() <= 5;
GeneralRange<Point> xRange = p -> p.getX() < 2 ? -1 : (p.getX() > 7 ? 1 : 0);
GeneralRange<Point> yRange = p -> 0;//p.getY() < 3 ? -1 : (p.getY() > 6 ? 1 : 0);
ArrayList<GeneralRange<Point>> ranges = new ArrayList<GeneralRange<Point>>();
ranges.add(xRange);
ranges.add(yRange);
Iterable<Point> results = kdt.rangeSearch(ranges);
System.out.println("Results");
for (Point p : results) {
System.out.println(p);
}
System.out.println(kdt.toString());
}
private class Node{
private KeyVal keyval;
private Node left, right;
private int n;
public Node(KeyVal keyval, int n) {
this.keyval = keyval;
this.n = n;
}
}
/**
* Create a new KD-tree from an array of key-value paired objects.
* @param axes A sequence of k GeneralCompare functions which compare based on each of the k axes.
* For example, to order a point based on x in the first axis and y in the second, the two
* GeneralCompares should correspond to x and y respectively. The length k of this list also
* defines the number of axes contained within the tree (the number of unique values on which
* to index the data).
* @param keyvals An array of key-value pairs to be inserted into the tree initially.
*/
public KDT(ArrayList<GeneralCompare<KeyVal>> axes, Comparable<KeyVal>[] keyvals) {
this.axes = axes;
root = buildTree(keyvals, 0, keyvals.length - 1, 0);
}
private Node buildTree(Comparable<KeyVal>[] keyvals, int lo, int hi, int depth) {
if (lo > hi) return null;
int axis = depth % getK();
int mid = (lo + hi) / 2;
MergeSort.sort(keyvals, lo, hi, axes.get(axis));
KeyVal median = (KeyVal) keyvals[mid];
System.out.println(median);
//TODO: fix size
Node newNode = new Node(median, 0);
newNode.left = buildTree(keyvals, lo, mid - 1, depth + 1);
newNode.right = buildTree(keyvals, mid + 1, hi, depth + 1);
newNode.n = size(newNode.left) + size(newNode.right) + 1;
return newNode;
}
/**
* Range search by providing k GeneralRange functions.
* @param range An ArrayList sequence of k GeneralRange functions for searching on
* each of the k axes. Must equal the number of axes used in the current tree.
* @return An Iterable object of all results found within the range specified.
*/
public Iterable<KeyVal> rangeSearch(ArrayList<GeneralRange<KeyVal>> range){
ArrayList<KeyVal> result = new ArrayList<KeyVal>();
rangeSearch(root, range, result, 0);
return result;
}
private void rangeSearch(Node x, ArrayList<GeneralRange<KeyVal>> range, ArrayList<KeyVal> result, int depth) {
if (x == null) return;
int axis = depth % getK();
GeneralRange<KeyVal> rg = range.get(axis);
System.out.println("Try: " + x.keyval);
int bounds = rg.isInBounds((KeyVal) x.keyval);
if (bounds == 0) {
System.out.println(pointInside(x.keyval, range));
if (pointInside(x.keyval, range)) {
result.add(x.keyval);
}
rangeSearch(x.left, range, result, depth + 1);
rangeSearch(x.right, range, result, depth + 1);
} else if (bounds > 0) {
rangeSearch(x.left, range, result, depth + 1);
} else if (bounds < 0)
rangeSearch(x.right, range, result, depth + 1);
return;
}
private boolean pointInside(KeyVal pt, ArrayList<GeneralRange<KeyVal>> range) {
for (int i = 0; i < axes.size(); i++)
if (range.get(i).isInBounds(pt) != 0) return false;
return true;
}
public int size() {
return size(root);
}
public int height() {
return height(root);
}
private int height(Node x) {
if (x == null) return 0;
return 1 + Math.max(height(x.left), height(x.right));
}
private int size(Node x) {
if (x == null) return 0;
else return x.n;
}
/**
* Get the number of axes in this tree.
* @return The number of axes, k, in the current tree.
*/
public int getK() {
return axes.size();
}
public String toString() {
return toString(root, "");
}
private String toString(Node x, String depth) {
if (x == null) return depth + "null\n";
String result = "";
result += depth + x.keyval.toString() + "\n";
result += toString(x.left, depth + " ");
result += toString(x.right, depth + " ");
return result;
}
}
......@@ -37,7 +37,7 @@ public class MergeSort{
int mid = lo + (n/2);
// Fill auxiliary array
System.out.println("lo, mid, hi: " + lo + ", " + mid + ", " + hi);
//System.out.println("lo, mid, hi: " + lo + ", " + mid + ", " + hi);
for(int k = lo; k <= hi; k++){
aux[k] = x[k];
......
package sort;
public class Range<Key extends Comparable<Key>> {
private final Bound boundType;
private final Key lower;
private final Key upper;
public Range(Bound bt) throws Exception {
if (bt == Bound.ANY) {
boundType = bt;
lower = null;
upper = null;
}
else
throw new Exception("Must provide ANY bound.");
}
public Range(Bound bt, Key upperOrLower) throws Exception {
if (bt == Bound.UPPER) {
upper = upperOrLower;
lower = null;
} else if (bt == Bound.LOWER) {
upper = upperOrLower;
lower = null;
}
else
throw new Exception("Must provide UPPER OR LOWER bound.");
boundType = bt;
}
public Range(Bound bt, Key lower, Key upper) throws Exception {
if (bt == Bound.LOWHIGH) {
this.lower = lower;
this.upper = upper;
} else
throw new Exception("Must provide LOWHIGH bound.");
this.boundType = bt;
}
public <T> boolean inBounds(T key) {
if (boundType == Bound.ANY) return true;
else if (boundType == Bound.LOWER) return gc.compare(lower, key) <= 0;
else if (boundType == Bound.UPPER) return gc.compare(upper, key) >= 0;
else return gc.compare(lower, key) <= 0 && gc.compare(upper, key) >= 0;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment