Implement override and overrideAll
This commit is contained in:
@ -13,14 +13,32 @@ public class RecursiveOrderedBinaryTreeNodeProcessor<V> extends OrderedBinaryTre
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean override(Pointer<BinaryTreeNode<V>> pointer, V from, V to, Comparator<V> cmp) {
|
public boolean override(Pointer<BinaryTreeNode<V>> pointer, V from, V to, Comparator<V> cmp) {
|
||||||
|
if (remove(pointer, from, cmp)) {
|
||||||
|
pointer.deref = insert(pointer.deref, to, cmp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean overrideAll(Pointer<BinaryTreeNode<V>> pointer, V from, V to, Comparator<V> cmp) {
|
public boolean overrideAll(Pointer<BinaryTreeNode<V>> pointer, V from, V to, Comparator<V> cmp) {
|
||||||
|
var count = removeAllWithCount(pointer, from, cmp);
|
||||||
|
if (count == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pointer.deref = insertNTimes(pointer.deref, to, cmp, count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BinaryTreeNode<V> insertNTimes(BinaryTreeNode<V> tree, V v, Comparator<V> cmp, int count) {
|
||||||
|
if (count == 0) {
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
tree = insert(tree, v, cmp);
|
||||||
|
return insertNTimes(tree, v, cmp, count-1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BinaryTreeNode<V> insert(BinaryTreeNode<V> tree, V v, Comparator<V> cmp) {
|
public BinaryTreeNode<V> insert(BinaryTreeNode<V> tree, V v, Comparator<V> cmp) {
|
||||||
if (tree == null) {
|
if (tree == null) {
|
||||||
@ -118,10 +136,14 @@ public class RecursiveOrderedBinaryTreeNodeProcessor<V> extends OrderedBinaryTre
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeAll(Pointer<BinaryTreeNode<V>> pointer, V v, Comparator<V> cmp) {
|
public boolean removeAll(Pointer<BinaryTreeNode<V>> pointer, V v, Comparator<V> cmp) {
|
||||||
|
return removeAllWithCount(pointer, v, cmp) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int removeAllWithCount(Pointer<BinaryTreeNode<V>> pointer, V v, Comparator<V> cmp) {
|
||||||
var tree = pointer.deref;
|
var tree = pointer.deref;
|
||||||
|
|
||||||
if (tree == null) {
|
if (tree == null) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var c = cmp.compare(v, tree.key);
|
var c = cmp.compare(v, tree.key);
|
||||||
@ -135,20 +157,19 @@ public class RecursiveOrderedBinaryTreeNodeProcessor<V> extends OrderedBinaryTre
|
|||||||
tree.key = getReplacementForRemoval(tree.left, tree, false);
|
tree.key = getReplacementForRemoval(tree.left, tree, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAll(pointer, v, cmp);
|
return 1 + removeAllWithCount(pointer, v, cmp);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
return removeAllRec(tree.left, v, cmp, tree, false);
|
return removeAllWithCountRec(tree.left, v, cmp, tree, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeAllRec(tree.right, v, cmp, tree, true);
|
return removeAllWithCountRec(tree.right, v, cmp, tree, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean removeAllRec(BinaryTreeNode<V> node, V v, Comparator<V> cmp, BinaryTreeNode<V> prev, boolean right) {
|
private int removeAllWithCountRec(BinaryTreeNode<V> node, V v, Comparator<V> cmp, BinaryTreeNode<V> prev, boolean right) {
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var c = cmp.compare(v, node.key);
|
var c = cmp.compare(v, node.key);
|
||||||
@ -176,15 +197,14 @@ public class RecursiveOrderedBinaryTreeNodeProcessor<V> extends OrderedBinaryTre
|
|||||||
node = prev.left;
|
node = prev.left;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllRec(node, v, cmp, prev, right);
|
return 1 + removeAllWithCountRec(node, v, cmp, prev, right);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
return removeAllRec(node.left, v, cmp, node, false);
|
return removeAllWithCountRec(node.left, v, cmp, node, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeAllRec(node.right, v, cmp, node, true);
|
return removeAllWithCountRec(node.right, v, cmp, node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,6 +9,7 @@ import org.junit.jupiter.params.provider.ArgumentsSource;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static aud.exam.prep.Tests.CMP;
|
import static aud.exam.prep.Tests.CMP;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@ -156,4 +157,73 @@ public abstract class OrderedTreeProcessorTest<T> {
|
|||||||
T t = asTree(list);
|
T t = asTree(list);
|
||||||
processor.print(t);
|
processor.print(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(ListProvider.class)
|
||||||
|
void testThat_overrideOfNotExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
||||||
|
T t = asTree(list);
|
||||||
|
list.sort(CMP);
|
||||||
|
|
||||||
|
var p = new Pointer<>(t);
|
||||||
|
assertFalse(processor.override(p, -1, -5, CMP));
|
||||||
|
assertFalse(processor.override(p, 999, -5, CMP));
|
||||||
|
t = p.deref;
|
||||||
|
|
||||||
|
assertTrue(processor.check(t, CMP));
|
||||||
|
assertIterableEquals(list, processor.iterate(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(ListProvider.class)
|
||||||
|
void testThat_overrideOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
||||||
|
T t = asTree(list);
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
var to = -(i*i) - 5;
|
||||||
|
|
||||||
|
var p = new Pointer<>(t);
|
||||||
|
assertTrue(processor.override(p, list.get(i), to, CMP));
|
||||||
|
list.set(i, to);
|
||||||
|
t = p.deref;
|
||||||
|
|
||||||
|
assertTrue(processor.check(t, CMP));
|
||||||
|
list.sort(CMP);
|
||||||
|
assertIterableEquals(list, processor.iterate(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(ListProvider.class)
|
||||||
|
void testThat_overrideAllOfNotExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
||||||
|
T t = asTree(list);
|
||||||
|
list.sort(CMP);
|
||||||
|
|
||||||
|
var p = new Pointer<>(t);
|
||||||
|
assertFalse(processor.overrideAll(p, -1, -5, CMP));
|
||||||
|
assertFalse(processor.overrideAll(p, 999, -5, CMP));
|
||||||
|
t = p.deref;
|
||||||
|
|
||||||
|
assertTrue(processor.check(t, CMP));
|
||||||
|
assertIterableEquals(list, processor.iterate(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(ListProvider.class)
|
||||||
|
void testThat_overrideAllOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
||||||
|
T t = asTree(list);
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
var from = list.get(i);
|
||||||
|
var to = -(i*i) - 5;
|
||||||
|
|
||||||
|
var p = new Pointer<>(t);
|
||||||
|
assertTrue(processor.overrideAll(p, from, to, CMP));
|
||||||
|
t = p.deref;
|
||||||
|
list.replaceAll(k ->
|
||||||
|
Objects.equals(k, from) ? to : k);
|
||||||
|
|
||||||
|
assertTrue(processor.check(t, CMP));
|
||||||
|
list.sort(CMP);
|
||||||
|
assertIterableEquals(list, processor.iterate(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user