So someone at work showed me the light -- you can do it with interfaces. Something like this:
public interface Selector {
Node getFromSide(Node t);
Node getToSide(Node t);
void setFromSide(Node parent, Node newFromSide);
void setToSide(Node parent, Node newToSide);
}
static class L2R implements Selector {
public Node getFromSide(Node t) {
return t.left;
}
public Node getToSide(Node t) {
return t.right;
}
public void setFromSide(Node parent, Node newFromSide) {
parent.left = newFromSide;
}
public void setToSide(Node parent, Node newToSide) {
parent.right = newToSide;
}
}
static class R2L implements Selector {
public Node getFromSide(Node t) {
return t.right;
}
public Node getToSide(Node t) {
return t.left;
}
public void setFromSide(Node parent, Node newFromSide) {
parent.right = newFromSide;
}
public void setToSide(Node parent, Node newToSide) {
parent.left = newToSide;
}
}
private final static L2R Left2Right = new L2R();
private final static R2L Right2Left = new R2L();
Node move1(Selector dir) {
Node newRoot;
Node oldParent;
oldParent = this;
newRoot = dir.getFromSide(this);
while(dir.getToSide(newRoot) != null) {
oldParent = newRoot;
newRoot = dir.getToSide(newRoot);
}
dir.setToSide(newRoot, this);
if(oldParent != this) {
dir.setToSide(oldParent, dir.getFromSide(newRoot));
dir.setFromSide(newRoot, dir.getFromSide(this));
}
dir.setFromSide(this, null);
return newRoot;
}
The key insight I was missing -- probably because of my programming-weltanshauung -- was that I was thinking too low-level. I can probably make the Python implementation more Pythonic, too, by using something like the above rather than a reference to an array written up at http://cpark.users.sonic.net/tree_stuff/
No comments:
Post a Comment