home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / programm / 3405 < prev    next >
Encoding:
Text File  |  1993-01-04  |  2.9 KB  |  62 lines

  1. Newsgroups: comp.programming
  2. Path: sparky!uunet!cis.ohio-state.edu!zaphod.mps.ohio-state.edu!rpi!batcomputer!cornell!karr
  3. From: karr@cs.cornell.edu (David Karr)
  4. Subject: Re: Locating duplicates
  5. Message-ID: <1993Jan4.175728.22640@cs.cornell.edu>
  6. Organization: Cornell Univ. CS Dept, Ithaca NY 14853
  7. References: <C07FJo.4vq@ux1.cso.uiuc.edu> <1993Jan2.041658.21596@organpipe.uug.arizona.edu> <DOUGM.93Jan2014723@titan.cs.rice.edu>
  8. Date: Mon, 4 Jan 1993 17:57:28 GMT
  9. Lines: 51
  10.  
  11. I posted a somewhat stupid reply to the following last night; hopefully I
  12. canceled it before it did too much damage.  I'll try to be wiser this time:
  13.  
  14. In article <DOUGM.93Jan2014723@titan.cs.rice.edu> dougm@titan.cs.rice.edu (Doug Moore) writes:
  15. >But if these are fixed size integers (like C ints), you can radix sort
  16. >in linear time anyway, which is as fast as you can reasonably expect.
  17.  
  18. The algorithm that follows is indeed linear time, but look at the
  19. constant factor:  
  20.  
  21. >  while (mask <= max && mask) /* <= 32 times on my machine */
  22. >[...]
  23. >      for (j = 0; j < n; ++j)
  24. ...etc.
  25.  
  26. The program is doing up to 32 passes over a set of loops (of which I
  27. just showed the first) that always execute 5 lines of code for every
  28. entry in the array.  That's up to 160*n lines of code to be executed,
  29. depending on the range of values in your array.  Is that really 
  30. better than a well-written O(n log n) sorting algorithm?
  31.  
  32. In fact what you're doing is changing K1*n*log(n) time to K2*n*log(m)
  33. where m is the largest integer in the array.  For K1 ~= K2, this is
  34. good if m << n (lots and lots of duplicates) but bad if m >> n (e.g. a
  35. moderate sized array with widely varying data, few duplicates and lots
  36. of holes in the "range" it covers).
  37.  
  38. Personally, for the latter case I like the suggestions to use either a
  39. flag array indexing the range of your data or a hashing scheme along
  40. with an array of flags.  You can reduce the amount of extra memory
  41. considerably in either case by using bits of a bit vector for flags
  42. rather than using whole bytes, though this entails a little extra run
  43. time.  Of course you need to consider how long it takes to obtain an
  44. array intialized to all zeros.  (Depends on the machine
  45. implementation, I'd think.)  If you have to loop through the array to
  46. initialize it, I think it might more than wipe out any speed advantage.
  47.  
  48. When the range of your data is large, e.g. values up to 2^32, the bit
  49. array ends up being half a gigabyte, a bit large for comfort, so you
  50. might make a few passes of the radix sort to partition the array into
  51. "segments" in each of which the first p digits of each number are
  52. constant.  Then walk the array once using the unsorted digits of each
  53. segment to index a flag array.  You only need to keep the array for
  54. the current segment.  I suggest radix sorting from the left rather
  55. than the right; this makes the resulting order bizarre but who cares,
  56. all you need is the segmentation and I suspect the indexing arithmetic
  57. is fastest on the low-order bits.
  58.  
  59. -- David Karr (karr@cs.cornell.edu)
  60.  
  61.  
  62.