use strict; use warnings; use Data::Dumper; my %predec; while () { chomp; my ($succ, $pred) = split /;/, $_; $pred = $succ if $pred eq ''; push @{$predec{$pred}}, $succ; } my $continue = 1; while ($continue) { $continue = 0; for my $pred (keys %predec) { my $succ = @{$predec{$pred}}[-1]; if (defined $succ and exists $predec{$succ} and scalar @{$predec{$succ}} != 0) { next if $succ eq $pred; push @{$predec{$pred}}, @{$predec{$succ}}; delete $predec{$succ}; $continue = 1; } $succ = @{$predec{$pred}}[0]; if (defined $succ and exists $predec{$succ} and scalar @{$predec{$succ}} != 0) { unshift @{$predec{$pred}}, @{$predec{$succ}}; delete $predec{$succ}; $continue = 1; } } } print "Data structure: \n", Dumper \%predec; print "\n\nResult:\n\n"; for my $key (keys %predec) { next if scalar @{$predec{$key}} == 0; print "$key => $key\n" and next if $key eq @{$predec{$key}}[0]; print "$key => $key\n"; print "$_ => $key\n" for @{$predec{$key}}; } __DATA__ 567;456 456;345 345;234 234;123 339;228 228;117 131; 435;324 324;213 372;