Skip to content

Instantly share code, notes, and snippets.

@munificent
Created October 11, 2013 21:50
Show Gist options
  • Save munificent/6942575 to your computer and use it in GitHub Desktop.
Save munificent/6942575 to your computer and use it in GitHub Desktop.
My solution to http://cslibrary.stanford.edu/109/TreeListRecursion.html. I think mine is more efficient than Nick's.
// This is a Dart solution to:
//
// Nick Parlante's "Great Tree-List Recursion Problem"
// http://cslibrary.stanford.edu/109/TreeListRecursion.html
//
// Before you read the code here, try to solve it youself first!
main() {
var tree = makeTree(100);
printTree(tree);
var list = treeToList(tree);
printList(list);
}
// Here's the solution:
class Node {
final int data;
Node left;
Node right;
Node(this.data);
}
/// Convert [tree] to a linked list and return the head node.
Node treeToList(Node tree) {
var previous;
var last;
// Traverse the tree in order, and replace every left pointer to its previous
// one instead of its child. (We can't do the right pointers here because
// we haven't traversed those yet.)
inOrder(tree, (node) {
last = node;
node.left = previous;
previous = node;
});
// Now walk the list along the previous chain and wire up the next pointers.
while (previous.left != null) {
previous.left.right = previous;
previous = previous.left;
}
// Make the list circular.
previous.left = last;
last.right = previous;
// Since we walked back to the beginning, this is now the head.
return previous;
}
/// Invoke [callback] on each node in [tree], in order.
void inOrder(Node tree, callback) {
if (tree.left != null) inOrder(tree.left, callback);
callback(tree);
if (tree.right != null) inOrder(tree.right, callback);
}
// Scaffolding:
Node makeTree(int numNodes) {
var nums = new Iterable.generate(numNodes, (i) => i).toList();
nums.shuffle();
var root = new Node(nums[0]);
for (var n in nums.skip(1)) {
insertInTree(root, n);
}
return root;
}
void insertInTree(Node tree, int n) {
if (n < tree.data) {
if (tree.left == null) {
tree.left = new Node(n);
} else {
insertInTree(tree.left, n);
}
} else {
if (tree.right == null) {
tree.right = new Node(n);
} else {
insertInTree(tree.right, n);
}
}
}
void printTree(Node tree, [String indent = ""]) {
if (tree.left != null) printTree(tree.left, indent + " ");
print("$indent${tree.data}");
if (tree.right != null) printTree(tree.right, indent + " ");
}
void printList(Node head) {
var node = head;
do {
print("${node.left.data} <- ${node.data} -> ${node.right.data}");
node = node.right;
} while (node != head);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment