Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
<version>3.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.27.0</version>
</dependency>
</dependencies>

<properties>
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/lodborg/intervaltree/TreeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ private TreeNode<T> balanceOut(){
// The tree is right-heavy.
if (height(right.left) > height(right.right)){
this.right = this.right.rightRotate();
this.right.height = Math.max(height(this.right.left), height(this.right.right)) + 1;
return leftRotate();
} else{
return leftRotate();
Expand All @@ -204,6 +205,7 @@ private TreeNode<T> balanceOut(){
// The tree is left-heavy.
if (height(left.right) > height(left.left)){
this.left = this.left.leftRotate();
this.left.height = Math.max(height(this.left.left), height(this.left.right)) + 1;
return rightRotate();
} else
return rightRotate();
Expand Down
93 changes: 90 additions & 3 deletions src/test/java/com/lodborg/intervaltree/TreeNodeTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.lodborg.intervaltree;

import com.lodborg.intervaltree.Interval.Bounded;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.*;

import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import com.lodborg.intervaltree.Interval.*;

import java.util.*;

public class TreeNodeTest {
@Test
Expand Down Expand Up @@ -234,4 +238,87 @@ public void test_iteratorRemoveDeletesInnerNodeAndPromotesTheSubtreeRoot(){
assertTrue(list.contains(next));
}
}

@Test
public void leftRightRotation() {

IntervalTree<Integer> tree = Mockito.mock(IntervalTree.class);
TreeNode<Integer> node = TreeNode.addInterval(tree, null, new IntegerInterval(100, 100, Bounded.CLOSED));
node = TreeNode.addInterval(tree, node, new IntegerInterval(50, 50, Bounded.CLOSED));
node = TreeNode.addInterval(tree, node, new IntegerInterval(75, 75, Bounded.CLOSED));

assertAVLHeightProperty(node);
assertHeight(node);
}

@Test
public void rightLeftRotation() {

IntervalTree<Integer> tree = Mockito.mock(IntervalTree.class);
TreeNode<Integer> node = TreeNode.addInterval(tree, null, new IntegerInterval(50, 50, Bounded.CLOSED));
node = TreeNode.addInterval(tree, node, new IntegerInterval(100, 100, Bounded.CLOSED));
node = TreeNode.addInterval(tree, node, new IntegerInterval(75, 75, Bounded.CLOSED));

assertAVLHeightProperty(node);
assertHeight(node);
}


@Test
public void randomIntervals() {

IntervalTree<Integer> tree = Mockito.mock(IntervalTree.class);
Random random = new Random();

TreeNode<Integer> node = TreeNode.addInterval(tree, null, new IntegerInterval(100, 100, Bounded.CLOSED));

for (int i = 0; i < 100_000; i++) {

int num = random.nextInt();
node = TreeNode.addInterval(tree, node, new IntegerInterval(num - 1, num + 1, Bounded.CLOSED));
}

assertAVLHeightProperty(node);
assertHeight(node);
}

private <T extends Comparable<T>> int assertHeight(TreeNode<T> node) {

if (node == null) {
return 0;
}

int leftHeight = assertHeight(node.left);
int rightHeight = assertHeight(node.right);

int height = Math.max(leftHeight, rightHeight) + 1;

assertThat(node.height, is(height));

return height;
}

private <T extends Comparable<T>> void assertAVLHeightProperty(TreeNode<T> root) {

if (root == null) {
return;
}

assertThat(root.height, greaterThan(0));

if (root.left == null && root.right == null) {
assertThat(root.height, CoreMatchers.is(1));
} else {
assertThat("Height of two subtrees should not differ by more than 1",
Math.abs(height(root.left) - height(root.right)), lessThanOrEqualTo(1));
}

assertAVLHeightProperty(root.left);
assertAVLHeightProperty(root.right);
}

private <T extends Comparable<T>> int height(TreeNode<T> root) {

return root == null ? 0 : root.height;
}
}