comp.lang.ada
 help / color / mirror / Atom feed
From: Jean-Marc Bourguet <jm@bourguet.org>
Subject: Re: list strawman
Date: 13 Jan 2002 11:18:35 +0100
Date: 2002-01-13T11:23:45+01:00	[thread overview]
Message-ID: <rtmr1a.c81.ln@192.168.0.2> (raw)
In-Reply-To: 7uir1a.s11.ln@192.168.0.2

Jean-Marc Bourguet <jm@bourguet.org> writes:

> There is a sligth difference with was is presented in Knuth. He use an
> additionnal flag in the record to mark the end of the sublists.  I
> didn't do that and used the fact that a sublist end when there is a
> drop in value.  This has a consequence that sublists may be merged
> inexpectedly and so some care must be taken not to go in O(N^2).

Here is a variant.  Instead of detecting chunks by a drop in value, I
mark the end of chunk with Null and keep the already constructed chunks
in an array.  To keep their number low, I merge them as they are
constructed.

Pure algorithm L is having

procedure Extract_Next_Chunk (Head  : in out Node_Ptr;
			      Chunk :    out Node_Ptr;
		              Slot  :    out Table_Index) is
   Slot := 1;
   Chunk := Head;
   Head := Chunk.Next;
   Chunk.Next := null;
end Extract_Next_Chunk;

instead of what is below.

-- 
Jean-Marc

   ---------------------------------------------------------------------------
   -- Natural List Merge Sort
   -- See D.E. Knuth, The Art Of Computer Programming, Volume 3, Second Edition
   -- Algorithm L section 5.2.4 modified according exercise 12 in the same
   -- section, modified to merge chunks as they are constructed instead of keeping
   -- them.  Already constructed chunks are kept in an array.  They are at most
   -- log_2(N).  Big existing chunk are put at their place in the array, this help
   -- in the presence of nearly sorted input.

   procedure Sort (Head : in out Node_Ptr);
   -- Sort the linked list Head.

   procedure Sort (Head : in out Node_Ptr) is
      
      type Table_Index is range 1 .. 64;

      procedure Extract_Next_Chunk (Head  : in out Node_Ptr;
				    Chunk :    out Node_Ptr;
				    Slot  :    out Table_Index) is
         Last    : Node_Ptr := Head;
         Current : Node_Ptr := Last.Next;
	 Size    : Integer := 1;
	 Next    : Integer := 2;
      begin -- Extract_Next_Chunk
         Chunk := Head;
	 Slot  := 1;
         while Current /= null loop
            pragma Assert (Current = Last.Next);
            if not Ordered (Last.Value, Current.Value) then
	       Last.Next := null;
	       Head := Current;
	       return;
	    end if;
            Last    := Current;
            Current := Last.Next;
	    Size := Size + 1;
	    if Size = Next then
	       Next := 2*Next;
	       Slot := Slot + 1;
	    end if;
         end loop;
	 Head := null;
         pragma Assert (Last.Next = null);
      end Extract_Next_Chunk;
      
      function Merge (L1, L2 : Node_Ptr) return Node_Ptr is
	 Current1 : Node_Ptr := L1;
	 Current2 : Node_Ptr := L2;
	 Last : Node_Ptr := null;
	 Result : Node_Ptr := null;
      begin
	 while Current1 /= null and Current2 /= null loop
	    if Ordered (Current1.Value, Current2.Value) then
	       if Last /= null then
		  Last.Next := Current1;
	       else
		  Result := Current1;
	       end if;
	       Last := Current1;
	       Current1 := Current1.Next;
	    else
	       if Last /= null then
		  Last.Next := Current2;
	       else
		  Result := Current2;
	       end if;
	       Last := Current2;
	       Current2 := Current2.Next;
	    end if;
	 end loop;
	 if Current1 /= null then
	    if Last /= null then
	       Last.Next := Current1;
	    else
	       Result := Current1;
	    end if;
	 elsif Current2 /= null then
	    if Last /= null then
	       Last.Next := Current2;
	    else
	       Result := Current2;
	    end if;
	 end if;
	 return Result;
      end Merge;
      
      type Node_Ptr_Table is array(Table_Index) of Node_Ptr;

      Chunk_Table : Node_Ptr_Table := (others => null);
      -- list pointed by chunk_table(i) as at least 2^(i-1) elements
      
      procedure Merge_With_Other_Chunks (Chunk : Node_Ptr; Slot : Table_Index) is
	 Current : Node_Ptr := Chunk;
	 I : Table_Index := Slot;
      begin -- Merge_With_Other_Chunks
	 while Chunk_Table(I) /= null loop
	    Current := Merge (Current, Chunk_Table(I));
	    Chunk_Table(I) := null;
	    I := I+1;
	 end loop;
	 Chunk_Table(I) := Current;
      end Merge_With_Other_Chunks;
      
      Aux : Node_Ptr;
      Slot : Table_Index;
      
   begin -- Sort
      if Head = null then
         return;
      end if;
      while Head /= null loop
	 Extract_Next_Chunk (Head, Aux, Slot);
	 Merge_With_Other_Chunks (Aux, Slot);
      end loop;
      for I in Table_Index loop
	 Head := Merge (Head, Chunk_Table(I));
      end loop;
   end Sort;




  reply	other threads:[~2002-01-13 10:18 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
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 [this message]
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