Implement override and overrideAll

This commit is contained in:
2021-09-04 16:00:54 +02:00
parent 159994b1ad
commit 5df44cbc44
2 changed files with 102 additions and 12 deletions

View File

@ -13,12 +13,30 @@ 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) {
return false; var count = removeAllWithCount(pointer, from, cmp);
if (count == 0) {
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
@ -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

View File

@ -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));
}
}
} }