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]