php链表笔记:链表的检测
<?php /** * Created by PhpStorm. * User: huizhou * Date: 2018/12/2 * Time: 11:48 */ /** * 链表的检测 * Class CheckCirclesList */ /** * 单链表类 */ class Node{ private $next; private $value; public function __construct($value = null) { $this->value = $value; } public function getValue(){ return $this->value; } public function setValue($value){ $this->value = $value; } public function getNext(){ return $this->next; } public function setNext($next){ $this->next = $next; } } /** * 找出带环链表的环的入口结点 * @param Node $pHead * @return Node */ function entryNodeOfLoop(Node $pHead){ $slow = $pHead; $fast = $pHead; while ($fast != null && $fast->getNext() !=null ){ /** 单链表中环的检测 首先设置两个指针,分别命名为fast和slow,fast指针每次向后移2步,slow指针每次向后移1步。 如果,fast指针最后走到尾结点,则没有环。 如果,fast指针和slow指针相遇,则证明有环。 **/ $slow = $slow->getNext(); // 慢指针走一步 $fast = $fast->getNext()->getNext(); // 快指针走两步 // 快慢指针环内相遇 if($slow === $fast){ // 快指针回到头结点 $fast = $pHead; // 同一速度再同时走 while ($slow != $fast){ $slow = $slow->getNext(); $fast = $fast->getNext(); } /** 环的起始结点的查询 当fast与slow相遇之后, fast指针从头结点开始走,每次走1步 当fast再次与slow相遇以后,相遇处的结点为环的入口结点 **/ // 两个相遇的点一定是环的入口 if ($slow == $fast){ return $fast; } } } } function test(){ // 创建一个带环的链表 $linkList = new Node(); $temp = $linkList; $node1 = new Node('1'); $temp->setNext($node1); $temp = $node1; $node2 = new Node('2'); $temp->setNext($node2); $temp = $node2; $node3 = new Node('3'); $temp->setNext($node3); $temp = $node3; $node4 = new Node('4'); $temp->setNext($node4); $node4->setNext($node2); // 尾节点指向第二个节点 //打印环 var_dump($linkList); //打印入口节点 $result = entryNodeOfLoop($linkList); var_dump($result); } test();