Re: Shuffling a linked list
- From: "Googmeister" <googmeister@xxxxxxxxx>
- Date: 29 Dec 2006 13:41:20 -0800
Richard Harter wrote:
On 29 Dec 2006 10:46:31 -0800, "Googmeister" <googmeister@xxxxxxxxx>
wrote:
Richard Harter wrote:
On Fri, 29 Dec 2006 18:07:16 +0100, Pascal Bourguignon
<pjb@xxxxxxxxxxxxxxxxx> wrote:
"A. Farber" <Alexander.Farber@xxxxxxxxx> writes:
Hello,
I have a doubly-linked list of 32 playing cards, which I'd like to
randomly and evenly (!) shuffle.
(For several reasons I'm not using an array, which I could go
through once, keeping swapping cards at random positions.)
I have a list head with 2 pointers - to the very 1st and to the
last elements and I have 2 macros to insert an element at the
"head" or at the "tail".
Does anybody please have a good algorithm for me?
Probably the simplest method is use an auxilliary array, put the cards
in it, use the standard O(n) shuffling algorithm, and relink the cards
into a doubly-linked list. All steps are O(n) and the code is simple in
each step.
I'm thinking of having an integer variable i which I'd increase
by one while going through my list. And if rand(i) < 1 then
I'd move that element at the "head" of the list. Which should
give each card a 1/32 possibility to land at the "head" position.
As stated, this doesn't make a lot of sense - all it would do is reverse
the list. Even if you have a changing epsilon(i) with a test rand(i) <
epsilon(i) it still wouldn't work. Consider, for example, the last
element in the list. In your scheme it could end up as the first
element or the last element but never anywhere inbetween.
Choose one random element in the list, remove it and put it in a new
list. Repeat until the original list is empty.
That won't quite do because you haven't specified how you find to find
the one random element. The obvious method is to traverse the list a
random distance. That will produce an O(n**2) algorithm. Given the
shortness of the list (32) that may well be acceptable but I wouldn't
exactly call it a good algorithm.
This is an interesting problem if we have the constraint that there is
no extra storage to be used. It obviously can be done in O(n * log n)
by converting the list into a balanced tree and then randomly extracting
elements one at a time. I don't think that there is an O(n) algorithm -
if there were you could use it to do constant time random accesses into
linked lists.
It can be done in O(n log n) with O(1) extra space, but your proposed
algorithm only does so if you assume the linked list has two pointers
per node (instead of the usual one).
The original statement was that the list was doubly linked. I quote:
"I have a doubly-linked list of 32 playing cards". I took that as a
given.
Yes, my mistake.
May I refine the challenge as follows: Given a singly linked list of
length n, randomly shuffle it using O(n) calls to rand, O(n log n) data
moves, and O(1) extra space.
You need at least n log n bits of randomness since there are n!
possible
outcomes and log n! ~ n log n. So, is it safe to assume each
call to rand() returns log n random bits?
.
- Follow-Ups:
- Re: Shuffling a linked list
- From: Richard Harter
- Re: Shuffling a linked list
- References:
- Shuffling a linked list
- From: A. Farber
- Re: Shuffling a linked list
- From: Pascal Bourguignon
- Re: Shuffling a linked list
- From: Richard Harter
- Re: Shuffling a linked list
- From: Googmeister
- Re: Shuffling a linked list
- From: Richard Harter
- Shuffling a linked list
- Prev by Date: Re: Shuffling a linked list
- Next by Date: Re: Shuffling a linked list
- Previous by thread: Re: Shuffling a linked list
- Next by thread: Re: Shuffling a linked list
- Index(es):
Relevant Pages
|