Array
(
[385] => 392
[386] => 392
[387] => 392
[390] => 402
[402] => 421
[405] => 401
[409] => 416
[410] => 401
[414] => 402
[416] => 389
[420] => 421
[421] => 422
[422] => 420
)
[420] => 421
[421] => 422
[422] => 420
$array = [
385 => 392,
386 => 392,
387 => 392,
390 => 402,
402 => 421,
405 => 401,
409 => 416,
410 => 401,
414 => 402,
416 => 389,
420 => 421,
421 => 422,
422 => 420,
];
foreach ($array as $key => $value) {
$level=0;
$leaf=[$key=>$level]; $v=$value;
while(true){
if(!isset($array[$v])) break;
$v=$array[$v];
if(isset($leaf[$v])) {
// loop found
// is it real loop ?
if($key==$v) {
printf("\n %s => %s", $key, $value);
}
break;
}
$leaf[$v]=++$level;
}
}
$result = [];
foreach ($arr as $n) {
for ($visited = []; array_key_exists($n, $arr); $visited[] = $n, $n = $arr[$n]) {
if (($i = array_search($n, $visited)) !== false) {
$loop = array_slice($visited, $i);
if (empty(array_intersect(array_column($result, 0), $loop))) {
$result[] = $loop;
}
break;
}
}
}
$result = [];
$visited = [];
$iLoop = -1;
foreach ($arr as $n) {
for ($iLoop++; isset($arr[$n]); $visited[$n] = $iLoop, $n = $arr[$n]) {
if (isset($visited[$n])) {
if ($visited[$n] === $iLoop) {
for ($loop = [ $m = $n ]; ($m = $arr[$m]) !== $n; $loop[] = $m) ;
$result[] = $loop;
}
break;
}
}
}
do {
$path = [key($array), $link = current($array)];
while (isset($array[$link2 = $link])) {
$link = $array[$link2];
unset($array[$link2]);
$pathPos = array_search($link,$path); // более для понятности, для длинных колец эффективнее хранить только ключи и искать по ним
if (false !== $pathPos) {
var_export(array_slice($path,$pathPos));
break;
}
$path[] = $link;
}
} while (false!==next($array));