comp.lang.ada
 help / color / mirror / Atom feed
From: Jean-Marc Bourguet <jm@bourguet.org>
Subject: Re: list strawman
Date: 11 Jan 2002 10:37:52 +0100
Date: 2002-01-11T10:37:56+01:00	[thread overview]
Message-ID: <3c3eb272$0$282$626a54ce@news.free.fr> (raw)
In-Reply-To: 4519e058.0201091037.325fbdbb@posting.google.com

dennison@telepath.com (Ted Dennison) writes:

> Jean-Marc Bourguet <jm@bourguet.org> wrote in message news:<3c3bfabc$0$3190$626a54ce@news.free.fr>...
> > Ted Dennison<dennison@telepath.com> writes:
> > 
> > > That's a good point. It would probably be fairly easy to alternate
> > > which side the pivot is taken from.
> > 
> > This will not change the behaviour in N^2 for a (nearly) sorted input.
> 
> After thinking about it harder, you are right. Everything will allways
> go on one side of the pivot, no matter which side you take it from. So
> no "dividing" will actually happen, which is where this
> divide-and-conquer algorithm gets its speed from.
> 
> > > I believe the splitting part of mergesort would involve a linear
> > > search for a linked-list. That would take us into O(n*2) territory,
> > > if not worse. In my student days I could figure out the exact
> > > factor...hmmm...perhaps its just another nlogn...
> > 
> > Merge sort can be implemented in O(N log N) worst case, with a O(N)
> > for an already sorted input.
> 
> OK. By arguing through repeated assertion, you are forcing to either
> ignore you, or do the work of proof myself. Since I made the first
> claim, its only fair that I do the work I guess...

I think the proof is in The Art Of Computer Programming (Knuth, volume
three).

> ...OK it looks like the work involved in doing *all* the splits using
> linear searches is (n/2 + 2(n/4) + 4(n/8) ....) where n>1. Since there
> is one of these factors for each "level", and there are logn levels,
> that should work out to roughly (n/2)logn, or O(n logn). So you are
> right that it is O(N log N) worst case. However, you are wrong about
> the best case. With a linked-list, that is *also* O(N log N).

Not tested, not even compiled, but it should show the principles.  I
think it is in the section "external sorting" of Knuth.  I think the
sort is stable which is an added bonus (but this should be verified).

type Node;   
type Node_Ptr is access Node;
type Node is record
   Next: Node_Ptr;
   Value: Value_Type;
end record;

procedure Sort (Head : in out Node_Ptr) is

   procedure Append(N : Node_Ptr; 
                    Last, Other: in out Node_Ptr;
                    L1, L2: out Node_Ptr) is
   begin
      if Last = null then
         Last := N;
         L1   := N;
      else if Last.Value <= N.Value then
         Last.Next := N;
         Last := N;
      else if Other = null then
         Other := Last;
         Last  := N;
         L2    := N;
      else
         declare
           Tmp : Node_Ptr := Last;
         begin
           Last := Other;
           Other := Tmp;
           Last.Next := N;
           Last := N;
         end;
      end if;
   end Append;

   procedure Split(Head: Node_Ptr; L1, L2: out Node_Ptr) is
      Current : Node_Ptr := Head;
      Last    : Node_Ptr := Null;
      Other   : Node_Ptr := Null;
   begin -- Split
      L1 := null
      L2 := null;
      while Current /= null loop
         declare
            Next : Node_Ptr := Current.Next;
         begin
            Append(Current, Last, Other, L1, L2);
            Current := Next;
         end;
      end loop;
      Last.Next := null;
      if Other /= null then
         Other.Next := null
      end if;            
   end Split;

   procedure Merge(L1, L2: in out Node_Ptr) is
      Current1 : Node_Ptr := L1;
      Current2 : Node_Ptr := L2;
      Last    : Node_Ptr := null;
      Other   : Node_Ptr := Null;
      Tmp     : Node_Ptr := Null;
   begin -- Merge
      L1 := null;
      L2 := null;
      while Current1 /= null and Current2 /= null loop
         if Current1.Value <= Current2.Value then
            declare
               Next : Node_Ptr := Current1.Next;
            begin
               Append(Current1, Last, Other, L1, L2);
               Current1 := Next;
            end;
         else
            declare
               Next : Node_Ptr := Current2.Next;
            begin
               Append(Current2, Last, Other, L1, L2);
               Current2 := Next;
            end;
         end if;
      end loop;
      if Current1 /= null then
         Tmp := Current1;
      else
         Tmp := Current2;
      end if;
      while Tmp /= null loop
         declare
            Next : Node_Ptr := Tmp.Next;
         begin
            Append(Tmp, Last, Other, L1, L2);
            Tmp := Next;
         end;
      end loop;
      Last.Next := null;
      if Other /= null then
         Other.Next := null
      end if;                     
   end Merge;

begin -- Sort
   if Head = Null then
      return;
   end if;
   Split(Head, L1, L2);
   while L2 /= Null loop
      Merge(L1, L2);
   end loop;
   Head = L1;
end Sort;

Each split and Merge phase are O(n).  If the list is sorted, only
Split is done.  Merge reduce the number of chunks by a factor 2 and
there is at most N chunks (if the list is in the reverse order), so
worse case is O(N log N).

-- 
Jean-Marc



  reply	other threads:[~2002-01-11  9:37 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-01-06 20:55 list strawman Stephen Leake
2002-01-07 15:56 ` Ted Dennison
2002-01-07 15:57   ` Ted Dennison
2002-01-07 16:33   ` Stephen Leake
2002-01-07 16:37     ` Stephen Leake
2002-01-07 19:31       ` Ted Dennison
2002-01-07 19:26     ` Ted Dennison
2002-01-07 22:05       ` Stephen Leake
2002-01-07 22:51         ` Ted Dennison
2002-01-08  0:48           ` Steven Deller
2002-01-08 15:32             ` Ted Dennison
2002-01-08 15:43               ` Jean-Marc Bourguet
2002-01-08 17:07                 ` Ted Dennison
2002-01-08 17:21                   ` Jean-Marc Bourguet
2002-01-08 19:12                     ` Ted Dennison
2002-01-09  8:09                       ` Jean-Marc Bourguet
2002-01-09 18:37                         ` Ted Dennison
2002-01-11  9:37                           ` Jean-Marc Bourguet [this message]
2002-01-11 17:03                             ` Ted Dennison
2002-01-11 17:47                               ` Jeffrey Carter
2002-01-12 15:10                               ` Jean-Marc Bourguet
2002-01-13 10:18                                 ` Jean-Marc Bourguet
2002-01-14 16:02                                 ` Ted Dennison
2002-01-14 16:22                                   ` Jean-Marc Bourguet
2002-01-08 19:57                     ` Steven Deller
2002-01-08 19:54                 ` Steven Deller
2002-01-08 19:54               ` Steven Deller
2002-01-08 20:46                 ` Ted Dennison
2002-01-08 21:21                   ` Stephen Leake
2002-01-08 21:49                     ` Ted Dennison
2002-01-09  9:21                       ` Thomas Wolf
2002-01-09 15:20                         ` Ted Dennison
2002-01-09 15:53                           ` Stephen Leake
2002-01-09 21:21                             ` Ted Dennison
2002-01-09 17:42                         ` Mark Lundquist
2002-01-09 21:02                           ` Jeffrey Carter
2002-01-10  8:47                             ` Thomas Wolf
2002-01-11 17:38                               ` Jeffrey Carter
2002-01-11 21:52                                 ` Chad Robert Meiners
2002-01-12  5:45                                   ` Jeffrey Carter
2002-01-12 22:20                                     ` Chad R. Meiners
2002-01-13 17:03                                       ` Jeffrey Carter
2002-01-13 23:47                                         ` Chad R. Meiners
2002-01-14  1:32                                           ` Ted Dennison
2002-01-14  5:12                                           ` Jeffrey Carter
2002-01-14  5:12                                           ` Jeffrey Carter
2002-01-10 14:39                           ` Ted Dennison
2002-01-11  5:34                             ` Mark Biggar
2002-01-12 12:20                               ` Simon Wright
2002-01-14 14:53                                 ` Matthew Heaney
2002-01-16  5:56                                   ` Simon Wright
2002-01-18  9:15                           ` Overridability of _private_ predefined "=" [was Re: list strawman] Vincent Marciante
2002-01-19 16:58                             ` Vincent Marciante
2002-01-19 22:42                               ` Nick Roberts
2002-01-09  3:10                     ` list strawman Ted Dennison
2002-01-09 19:09                       ` Ted Dennison
2002-01-08 21:26               ` Georg Bauhaus
2002-01-08 22:13                 ` Ted Dennison
2002-01-09 20:52               ` Jeffrey Carter
2002-02-17 15:04 ` Florian Weimer
2002-02-17 15:05 ` Florian Weimer
2002-02-18  1:43   ` Stephen Leake
2002-02-18  8:57     ` Florian Weimer
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox