php 判斷是否有環存在

2021-10-25 07:26:51 字數 3326 閱讀 4721

如果乙個鍊錶存在迴圈, 則代表該鍊錶有環,其中,可能是部分迴圈, 也可能是首尾相接的迴圈鍊錶, 如下圖

在後面形成環的單鏈表

首尾相接的迴圈單鏈表

解析這裡我們還需要用到快慢指標, 快慢指標同時從煉表頭出發, 快指標每次走2步,慢指標每次走1步,當快指標走到了末尾時, 代表該鍊錶不是環形鍊錶

反之,當快指標追上了慢指標,則代表該鍊錶是環形鍊錶

理解這個就好像我們在操場跑步一樣, 跑道是環形的, 兩個人賽跑,乙個跑的快, 乙個跑的慢,如果我們不讓他停下來,跑的快的人總會'追'上跑的慢的人

slow->1->2->3->4->5

當慢指標走到5時, 快慢指標相遇,則這個鍊錶是環形鍊錶

下面我們就使用**來實現驗證是否為有環的單鏈表

**實現,完整**在最下面

/**

* 判斷鍊錶是否有環

* @param $head

* @return bool

*/public function iscyclelinkedlist($head)

}return false;

}

分析

由上題可知,按照快指標每次走2步,慢指標每次走1步的方式,發現快指標和慢指標重合,確定了單向鍊錶有環路了。接下來,讓快指標回到鍊錶的頭部,重新走,每次步長不是走2了,而是走1,那麼當快指標和慢指標再次相遇的時候,就是環路的入口了。

**實現

/**

* 判斷鍊錶是否有環, 並找到環的入口

* @param $head

* @return bool

*/public function findloopentrance($head)

}if ($fast === null || $fast->next === null)

$fast = $head;

while ($fast !== $slow)

return $fast->data;

}

這裡我們就不考慮鍊錶有環的問題了(其實是我不想去研究了,下次有時間了再畫圖補上)

假設兩個單鏈表都沒有環,如果他們相交, 則他們的尾指標一定是相同的,我們只要比較兩個鍊錶的尾結點即可,如下圖:

**實現

/**

* 判斷兩個鍊錶是否相交

* @param $l1

* @param $l2

* @return bool

*/public function isintersect($l1, $l2)

while ($l1->next !== null)

while ($l2->next !== null)

return $l1 === $l2;

}

假如鍊錶有環,判斷是否相交

<?php 

/** * created by phpstorm.

* author: xu shantong * date: 19-8-10

* time: 下午3:09

*/class node

}class iscyclesinglelinkedlist

}return false;

}/**

* 判斷鍊錶是否有環, 並找到環的入口

* @param $head

* @return bool

*/public function findloopentrance($head)

}if ($fast === null || $fast->next === null)

$fast = $head;

while ($fast !== $slow)

return $fast->data;

}/**

* 判斷兩個鍊錶是否相交

* @param $l1

* @param $l2

* @return bool

*/public function isintersect($l1, $l2)

while ($l1->next !== null)

while ($l2->next !== null)

return $l1 === $l2;

}//todo 判斷有環鏈表是否相交

}$node1 = new node(1);

$node2 = new node(2);

$node3 = new node(3);

$node4 = new node(4);

$node5 = new node(5);

$node6 = new node(6);

$node1->next = $node2;

$node2->next = $node3;

$node3->next = $node4;

$node4->next = $node5;

$node5->next = $node6;

// 第6個節點指向了第三個節點, 形成了迴圈

$node6->next = $node3;

$linkedlist = new iscyclesinglelinkedlist();

// 判斷鍊錶是否有環

var_dump($linkedlist->iscyclelinkedlist($node1)); // true

// 找出環的入口

var_dump($linkedlist->findloopentrance($node1)); // 3

// 判斷兩個鍊錶是否相交

$node6->next = null; // 重置node6的指標, 使鍊錶沒有環

var_dump($linkedlist->isintersect($node3, $node1)); // true

var_dump($linkedlist->isintersect($node3, new node(0))); // false

var_dump($linkedlist->isintersect($node3, new node('head', $node1))); // true

判斷是否存在負環

第1行 乙個整數 f表示接下來會有 f個農場說明。每個農場第一行 分別是三個空格隔開的整數 n,m和 w 第2行到 m 1行 三個空格分開的數字 s,e,t 描述,分別為 需要 t秒走過s和 e之間的雙向路徑。兩個區域可能由乙個以上的路徑來連線。第m 2到 m w 1 行 三個空格分開的數字 s,e...

判斷單鏈表是否存在環

有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...

判斷單鏈表是否存在環

判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如何找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 ...