Thursday, April 03, 2008

What are pointers and why should I learn about them? -- Part 2

OK, I was wrong about java -- probably because I'm rather a C/assembly dinosaur3 and I think in terms of nouns (e.g., pointers) rather than verbs (e.g., a method that sets the appropriate member of the structure).

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: