Hi, Mark, :)

On Sun, 8 Dec 2002, Mark Goland wrote:

> I am having problems printing this doubly list. the bug statment
> prints the expacted so I think I have the list setup right, but I
> cant get this list to print in reverse... any ideas ??

> #!/usr/bin/perl -w

# Always do this.
use strict;
use warnings;

> $debug=1;

> for($i=1;$i<10;$i++){
>       $list = {value=>$i,prev=>$list,next=>${prev} };
>  print "prev=$prev\tlist=$list\n" if( $debug);
>       $prev= $list;
>
> }

Since $prev and $list are global variables and you always set $prev to
list in the loop, how do you expect to go backwards ("reverse") with
your second iterator?  $prev == $list at the end of every iteration!
The only way to go backwards would be to store the head of the list
like so:

my $head;

for( my $i = 1;... ) {
   $list = ...;
   $head ||= $list;
   ...
}

That sets head equal to the first list member you create.

However, you have a larger problem.  You can't possibly go backwards
because your first element has both ->{next} *and* ->{prev}
undefined.  This shouldn't be the case in a double-linked list.

Also, your algorithm is incorrect.  If you slightly change the debug
output statement to look like this:

printf "\$list->{prev} = %s \t \$list->{next} = %s\n",
   $list->{prev},
   $list->{next} if $debug;

You'll see the problem.  Here's a sample run:

$ ./bob.pl
Use of uninitialized value in printf at ./bob.pl line 12.
Use of uninitialized value in printf at ./bob.pl line 12.
$list->{prev} =          $list->{next} =
$list->{prev} = HASH(0xa04116c)          $list->{next} = HASH(0xa04116c)
$list->{prev} = HASH(0xa066678)          $list->{next} = HASH(0xa066678)
$list->{prev} = HASH(0xa066630)          $list->{next} = HASH(0xa066630)
$list->{prev} = HASH(0xa0665e8)          $list->{next} = HASH(0xa0665e8)
$list->{prev} = HASH(0xa0665a0)          $list->{next} = HASH(0xa0665a0)
$list->{prev} = HASH(0xa066558)          $list->{next} = HASH(0xa066558)
$list->{prev} = HASH(0xa066510)          $list->{next} = HASH(0xa066510)
$list->{prev} = HASH(0xa0664c8)          $list->{next} = HASH(0xa0664c8)

Umm, ->{prev} and ->{next} are the SAME FOR EVERY ELEMENT.  So, you've
in a sense created a single linked list with an additional, un-needed
data member for each element.

The problem is that when creating a linked list, you never know the
address (er, reference in perl) of the *next* element.  So, in your
loop you have to "look back" and set the previous element's ->{next}
"pointer" (again, "reference" in perl) to the current element.  Your
algorithm didn't do this; hence the single linked list you created.

Try this on for size:

my ($head, $tail);

my $link;
for( my $i = 1; $i < 10; ++$i ) {
   $link = { value => $i,
             next => undef,
             prev => $link };
   $head ||= $link;
   $link->{prev}->{next} = $link if $link->{prev};
}
$tail = $link;

Let me know if you have any questions.

---Jason


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to