Earlier quoted context omitted.
Threaded trees was what I had in mind.[1] I believe the example there still talks of checking a visited list, though. Either a misunderstanding on my part, or on that page. I'll have to check on my books. Later, sadly. :) [1] http://en.wikipedia.org/wiki/Threaded_binary_tree Edit: Apologies for a quick edit. I remembered I had a short implementation on my computer. Basically, when you follow a link, you know if it wa…
Ah, great, thanks. I wasn't thinking about modifications to the tree.
Lampsort: Leslie Lamport's Non-recursive Quicksort
31–40 of 46 posts
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#32TL;DR: if you have an algorithm that makes two recursive calls and it doesn't matter what order you do them in (e.g. Quicksort) then you can rewrite that algorithm to use a set of sub-problems in stead of a stack of sub-problems. The latter is what you (implicitly) get when you write an algorithm recursively. A much more interesting observation would have been to note that you could accomplish the same thing by intro…
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#33> His trick is to ask the audience to give a non-recursive version of Quicksort, and of course everyone starts trying to remove the recursion, for example by making the stack explicit or looking for invertible functions in calls. But his point is that recursion is not at all fundamental in Quicksort. I'm not completely sure what distinction Meyer is trying to draw between the implementation he discusses, and "making…
Is the point that the order you pull things out of the
set doesn't matter, so demanding that it behave as a
stack is overly prescriptive?
Right. In fact, there are several parts of the algorithm that are not really fundamental; one is how you pick the pivot, and another is how you perform the partitioning (ensuring that all elements before the pivot are less and all elements after are greater).Lamport's point is that if you look at the fundamentals of the quicksort algorithm, which are that you must pick a pivot, partition such that smaller values come before and larger values come after, and then at some point later apply the same two steps to the two intervals [start, pivot) and (pivot, end].
Any algorithm that follows that specification will correctly sort the array, and then you can tweak exactly how you do that depending on your constraints. You could do it recursively, you could do it iteratively, you could divide it up into separate threads until you have one thread per processor each of which does the recursive or iterative algorithm on a private work list, you could do a worker pool in which each worker takes intervals from the set of remaining intervals to sort, etc. And likewise, you can tweak how you pick the pivot (picking the first element in the array is usually a bad idea, as it gives worst case behavior for already sorted arrays), and tweak how you perform the partitioning.
Anyhow, he didn't go into this kind of detail, he just pointed out that thinking about the fundamental specification can help get you away from the details of a particular implementation.
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#34Earlier quoted context omitted.
> There are ways to do a DFS of a tree without any sort of stack, though What do you mean by this? You need a way to say that the unexplored nodes we've most recently found are the ones we explore first. How do you do that (with constant time operations) without what's effectively a stack?
Threaded trees was what I had in mind.[1] I believe the example there still talks of checking a visited list, though. Either a misunderstanding on my part, or on that page. I'll have to check on my books. Later, sadly. :) [1] http://en.wikipedia.org/wiki/Threaded_binary_tree Edit: Apologies for a quick edit. I remembered I had a short implementation on my computer. Basically, when you follow a link, you know if it wa…
This sounds like the visited list again...
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#35TL;DR: if you have an algorithm that makes two recursive calls and it doesn't matter what order you do them in (e.g. Quicksort) then you can rewrite that algorithm to use a set of sub-problems in stead of a stack of sub-problems. The latter is what you (implicitly) get when you write an algorithm recursively. A much more interesting observation would have been to note that you could accomplish the same thing by intro…
That's a good observation. It should go without saying that recursion can always be expressed iteratively. Lamport is inclined to make observations like this, e.g. his sequential consistency concept which states that concurrency is always equivalent to a serial process. But don't you mean "multiple recursive calls", not specifically two?
Yes, of course.
Exercise for the non-lazy lurker: can you generalize the Quicksort algorithm based on this? Is there any benefit to doing so?
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#36Earlier quoted context omitted.
Threaded trees was what I had in mind.[1] I believe the example there still talks of checking a visited list, though. Either a misunderstanding on my part, or on that page. I'll have to check on my books. Later, sadly. :) [1] http://en.wikipedia.org/wiki/Threaded_binary_tree Edit: Apologies for a quick edit. I remembered I had a short implementation on my computer. Basically, when you follow a link, you know if it wa…
"Again, keep note of whether it was a thread or not." This sounds like the visited list again...
if (!followedThread && left != null)
set followedThread
Only node you really have to special case is the root node, and you can do that by making its right.node == null. Then you just do this while curNode != null.That make sense? (Also... very possible that I made a mistake here...)
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#37Earlier quoted context omitted.
That's a good observation. It should go without saying that recursion can always be expressed iteratively. Lamport is inclined to make observations like this, e.g. his sequential consistency concept which states that concurrency is always equivalent to a serial process. But don't you mean "multiple recursive calls", not specifically two?
> But don't you mean "multiple recursive calls", not specifically two? Yes, of course. Exercise for the non-lazy lurker: can you generalize the Quicksort algorithm based on this? Is there any benefit to doing so?
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#38TL;DR: if you have an algorithm that makes two recursive calls and it doesn't matter what order you do them in (e.g. Quicksort) then you can rewrite that algorithm to use a set of sub-problems in stead of a stack of sub-problems. The latter is what you (implicitly) get when you write an algorithm recursively. A much more interesting observation would have been to note that you could accomplish the same thing by intro…
Effectively, this is what Golang's "go" construct does. Combined with channels you can construct an arbitrary dependency graph as well.
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#39Earlier quoted context omitted.
> But don't you mean "multiple recursive calls", not specifically two? Yes, of course. Exercise for the non-lazy lurker: can you generalize the Quicksort algorithm based on this? Is there any benefit to doing so?
Since sorting is inherently a one-dimensional activity, I doubt it. Philosophically speaking, binary cuts are associated with qualitative phenomena, hot and cold being one of the prototypes (light and dark is another). Bergson or Deleuze elevate this kind of thing to a metaphysical level but I think there's an underlying simplistic aspect to it. Someone gives you a line, there's not much you can do but split it into…
Imagine you had 100 billion items to sort and 10,000 cores to put to work. Would that change your answer?
Re: Lampsort: Leslie Lamport's Non-recursive Quicksort
#40TL;DR: if you have an algorithm that makes two recursive calls and it doesn't matter what order you do them in (e.g. Quicksort) then you can rewrite that algorithm to use a set of sub-problems in stead of a stack of sub-problems. The latter is what you (implicitly) get when you write an algorithm recursively. A much more interesting observation would have been to note that you could accomplish the same thing by intro…
This would be the case for a pure function: http://en.wikipedia.org/wiki/Pure_function
One of the selling points of pure functional languages is the potential optimizations the compiler can theoretically do, including using multiple cores to evaluate a program, without any explicit hints from the programmer.