In looking for a solution to this question, I ran across some old binary tree code by Daniel Lichtblau, reproduced below:
Clear[leftsubtree, rightsubtree, nodevalue, emptyTree, treeInsert]
leftsubtree[{left_, _, _}] := left
rightsubtree[{_, _, right_}] := right
nodevalue[{_, val_, _}] := val
emptyTree = {};
treeInsert[emptyTree, elem_] := {emptyTree, elem, emptyTree}
treeInsert[tree_, elem_] /; SameQ[nodevalue[tree], elem] := tree
treeInsert[tree_, elem_] /; OrderedQ[{nodevalue[tree], elem}] :=
{leftsubtree[tree],
nodevalue[tree], treeInsert[rightsubtree[tree], elem]}
treeInsert[tree_, elem_] := {treeInsert[leftsubtree[tree], elem],
nodevalue[tree], rightsubtree[tree]}
When mapped onto a list, treeInsert gives you a sorted duplicate free list. For example,
tr = {};
Scan[(tr = treeInsert[tr, #]) &, RandomInteger[100, 5]];
Flatten@tr
(* {13, 28, 53, 59, 88} *)
On my machine, this takes ~2 s to process RandomInteger[10, 10^5], but this increases to nearly 20 s with RandomInteger[10, 10^6]. There are likely other techniques to speed this up, but I am curious as to how memoization could be adapted to this problem. At issue, though, is that the tree changes with each insertion, and so it cannot be used directly for memoization because the definition depends directly on that form. How would one do this?
Edit: as I discovered in my own testing, Fold works much better than Scan for creating a tree, as follows
tr = Fold[treeInsert, {}, RandomInteger[100, 5]];
Flatten@tr
(* {13, 28, 53, 59, 88} *)
Update: while my question, per se, was not answered directly, the answers themselves indicated that there were better ways to accomplish what I wanted. In the end, I chose the one I did for two reasons: speed and simplicity.
Min[list]-1andMax[list]+1, then useCompile, then replace back. This way, you can keep it almost as fast as without infinities. – Leonid Shifrin Apr 23 '12 at 18:24treeInsert[tree_, DirectedInfinity[d_]]and set a flag that can be handled later. It would still involve processing the elements one at a time, as opposed to within a compiled for loop, and would likely have to involveInternal`Baginstead of aList. – rcollyer Apr 23 '12 at 18:30