comp.lang.ada
 help / color / mirror / Atom feed
* Help: my list adt is broken
@ 2001-02-11 21:05 chris.danx
  2001-02-11 21:08 ` chris.danx
  2001-02-12 14:55 ` Ted Dennison
  0 siblings, 2 replies; 18+ messages in thread
From: chris.danx @ 2001-02-11 21:05 UTC (permalink / raw)


Hi,

i seem to have a problem with my (doubly) linked list ADT, and i can't
figure out what's wrong.

here is the output of the test program

>     -- display list before it get a choppin'
>    display a list of  5 elements
 >    5 4 3 2 1

>    -- remove head
>    display a list of  4 elements
>    4 3 2 1

>    -- remove an arbitary element
>    display a list of  3 elements
>    4 2 1

>    -- remove tail
>    display a list of  2 elements
>    4 2 1

>    -- remove head again
>    display a list of  1 elements
>    2 1

>    -- remove last element
>    no elements


i think the problem occurs when removing the tail.  it doesn't seem to be
erased but it should be.  i know
it's removed one from the size variable, so the code should be executed in
full.


i think the errror lies in the following routine, but i can't see it.

   -- remove item at current position from list;
   -- position will no longer be valid after execution;
   --
   -- will raise
   --   1. empty_list_error if list empty;
   --   2. position_error if position invalid;
   --
   procedure remove (l : in out list;
                     p : in out list_position) is
      t   :   list_position;
   begin
      if is_empty(l) then
         raise empty_list_error;
      end if;
      if is_invalid(p) then
         raise position_error;
      end if;

      if head(l) = p then
         l.head := p.next;
         l.size := l.size - 1;
         delete_node(p);
      elsif tail(l) = p then
         l.tail := p.prev;
         l.size := l.size - 1;
         delete_node(p);
      else
         t := p;

         -- dereference p;
         t.prev.next := p.next;
         t.next.prev := p.prev;

         -- delete p;
         delete_node(p);

         l.size := l.size - 1;
      end if;
   end remove;


i've also included the delete_node routine

   -- delete a node and give its' space back to pool;
   --
   procedure delete_node (n : in out list_position) is
      procedure free
         is new ada.unchecked_deallocation
                (node, list_position);
   begin
      free (n);
   end delete_node;

if it's any help.

list_position is simply a pointer to a node which contains

    1.        a pointer to the next and previous nodes
    2.        the data

oh, i almost forgot, the list type maintains a pointer to the head and tail,
as well as the size of the list.

i think i've been staring at it too long!!!  i'll let someone else takeover.


Thanks in advance,
Chris Campbell















^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: Help: my list adt is broken
@ 2001-02-13 15:35 schwarza
  2001-02-14 11:47 ` John English
  0 siblings, 1 reply; 18+ messages in thread
From: schwarza @ 2001-02-13 15:35 UTC (permalink / raw)
  To: chris.danx, comp.lang.ada

From: "chris.danx" <chris.danx@ntlworld.com>


Actually, it isn't a homework assignment!

  <sigh> I always get in trouble when I jump to contusions. Sorry!

  [1] Algorithms for linked lists are standard fare in textbooks
      on Data Structures and on Algorithms (and sometimes on
      Compiler Design). I assume that you have them and have
      looked at them. Mine are old (old ... old - but still good.)
  [2] There are a number of Ada implementations of the C Standard
      Template Library (?) STL. If you are interested I'll try to
      find some URL's and send them to you.
  [3] I have a full implementation of SLIP, a really full implementation
      of doubly linked lists akin to LISP, written in C and Ada83,
      both languages without class. And, I have a word document which
      is a retyped version (with diagrams) of a SLIP description
      written in Sammett's book "Programming Languages", 1967. The
      book stuff is excellent. My internal documentation is almost
      non-existent. If you'd like, I'll send the whole nine yards
      to you - tho' I advise a shovel for the dirt.

      (There are some reasonable extensions yet to be done that have
      been on my 'wannado' list for years - hint, hint, hint. One is
      an implementation for dynamic memory management. Because the
      'language' is written as an API it is really not possible to
      write something for dynamic memory management (with garbage
      collection) but that doesn't mean that something can't be
      done.)

  Other than that, nothing. Sorry.

art






^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: Help: my list adt is broken
@ 2001-02-12 21:14 schwarza
  2001-02-12 23:09 ` chris.danx
  0 siblings, 1 reply; 18+ messages in thread
From: schwarza @ 2001-02-12 21:14 UTC (permalink / raw)
  To: comp.lang.ada

Chris;

There are exactly two (2) ways of implementating a doubly-linked
list (unless I become reasonable - nah, never happen):

[1] Each end of the doubly linked list terminates in a null and
    the list head points to the first element of the list:

    ptr ->   null <- cell -> ... <- cell -> null

[2] There is a unique list header which points to both the list
    header and tail (and is itself a list cell) with a pointer
    to the header cell being the external 'name' of the list:

    ptr ->   unique list header cell
                                top   -> <- cell -> ... <- cell -> .
                                bot                     ->         |
                                 ^                                 |
                                 |                                 |
                                 .---------------------------------.

I prefer two to one (2 to 1) but that is not material.

Now, to do any list switching the order of operations is very, very
important. If you don't do things in the proper order, carefully,
things get fouled up fast. So let's see:

Suppose we do the following:

   1. Save the left pointer of the first cell.
   2. Put into the left pointer of the first cell, the left pointer
      of the 'new cell'.
   3. Put into the left pointer of the second cell, the (saved) left
      pointer of the first cell.
   4. Put into the right pointer of the cell pointed to by the second
      cell a pointer to the current cell. And here is where the two
      implementations differ. For [1], it is possible for the left
      pointer of the second cell to be null. For [2] there is no such
      worry (it works in all cases).
   5. Repeat for the right pointers.
   6. If you have implemented [1], then some fixup is required:
      a. If the second cell is the list top, then the 'ptr' must
         be changed to the first cell (the new list top).
      b. If the first cell is the list top then the contrawise
         operation has to be done.

And now for the kicker. This is not a place to get your homework
assignments done. Having said that, let me amplify a comment concerning
debugging (instrumenting your code with output statements). Code for
failure!! Assume nothing (NOTHING) will work correctly and provide
print statements accordingly. It's easier than asking questions. And,
allow the print statements to be turned on or off, as in:

   if this_is_some_kind_of_debug_thing then PRINT;

Disappointingly you will find that the volume of code required to code
for failure is larger than that for your actual classroom assignments.
Encouragingly you will shine amongst your peers because you will be able
to identify your errors quickly and solve them even more quickly.

art

PS: If any of you are real, real old programmers then [2] is SLIP
(Symmetric
    LIst Processor) from way, way back (circa 1960).  I believe that Eliza
    was programmed in SLIP and in FORTRAN at MIT.

PSST: I am a real, real old programmer and still have copies of the
original
    SLIP implementation circa 1964 at the University of Wisconsin; in
FORTRAN.






^ permalink raw reply	[flat|nested] 18+ messages in thread
* Help: my list adt is broken
@ 2001-02-11 21:04 chris.danx
  2001-02-11 23:01 ` Larry Hazel
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: chris.danx @ 2001-02-11 21:04 UTC (permalink / raw)


Hi,

i seem to have a problem with my (doubly) linked list ADT, and i can't
figure out what's wrong.

here is the output of the test program

>     -- display list before it get a choppin'
>    display a list of  5 elements
 >    5 4 3 2 1

>    -- remove head
>    display a list of  4 elements
>    4 3 2 1

>    -- remove an arbitary element
>    display a list of  3 elements
>    4 2 1

>    -- remove tail
>    display a list of  2 elements
>    4 2 1

>    -- remove head again
>    display a list of  1 elements
>    2 1

>    -- remove last element
>    no elements


i think the problem occurs when removing the tail.  it doesn't seem to be
erased but it should be.  i know
it's removed one from the size variable, so the code should be executed in
full.


i think the errror lies in the following routine, but i can't see it.

   -- remove item at current position from list;
   -- position will no longer be valid after execution;
   --
   -- will raise
   --   1. empty_list_error if list empty;
   --   2. position_error if position invalid;
   --
   procedure remove (l : in out list;
                     p : in out list_position) is
      t   :   list_position;
   begin
      if is_empty(l) then
         raise empty_list_error;
      end if;
      if is_invalid(p) then
         raise position_error;
      end if;

      if head(l) = p then
         l.head := p.next;
         l.size := l.size - 1;
         delete_node(p);
      elsif tail(l) = p then
         l.tail := p.prev;
         l.size := l.size - 1;
         delete_node(p);
      else
         t := p;

         -- dereference p;
         t.prev.next := p.next;
         t.next.prev := p.prev;

         -- delete p;
         delete_node(p);

         l.size := l.size - 1;
      end if;
   end remove;


i've also included the delete_node routine

   -- delete a node and give its' space back to pool;
   --
   procedure delete_node (n : in out list_position) is
      procedure free
         is new ada.unchecked_deallocation
                (node, list_position);
   begin
      free (n);
   end delete_node;

if it's any help.

list_position is simply a pointer to a node which contains

    1.        a pointer to the next and previous nodes
    2.        the data

oh, i almost forgot, the list type maintains a pointer to the head and tail,
as well as the size of the list.

i think i've been staring at it too long!!!  i'll let someone else takeover.


Thanks in advance,
Chris Campbell













^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2001-02-14 11:47 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-02-11 21:05 Help: my list adt is broken chris.danx
2001-02-11 21:08 ` chris.danx
2001-02-12 14:55 ` Ted Dennison
  -- strict thread matches above, loose matches on Subject: below --
2001-02-13 15:35 schwarza
2001-02-14 11:47 ` John English
2001-02-12 21:14 schwarza
2001-02-12 23:09 ` chris.danx
2001-02-13  1:42   ` Jeffrey Carter
2001-02-11 21:04 chris.danx
2001-02-11 23:01 ` Larry Hazel
2001-02-12  0:29 ` tmoran
2001-02-12  0:29 ` Chad R. Meiners
2001-02-12 12:17 ` chris.danx
2001-02-12 12:50 ` chris.danx
2001-02-12 14:23   ` John English
2001-02-12 15:10     ` chris.danx
2001-02-12 17:33 ` chris.danx
2001-02-12 20:00   ` tmoran

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