如果乙個鍊錶存在迴圈, 則代表該鍊錶有環,其中,可能是部分迴圈, 也可能是首尾相接的迴圈鍊錶, 如下圖
在後面形成環的單鏈表
首尾相接的迴圈單鏈表
解析這裡我們還需要用到快慢指標, 快慢指標同時從煉表頭出發, 快指標每次走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 如果鍊錶為存在環,如何找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 ...