您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么在php中使用環形鏈表解決約瑟夫問題,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
約瑟夫問題:
Josephu問題為:設編號為1,2,...n的n個人圍坐一圈,約定編號為k(1<=k<=n)的人從1開始報數,數到m的那個人出列,它的下一位又從1開始報數,數到m的那個人又出列,依次類推,直到所有人出列為止,由此產生一個出隊編號的序列。并求出最后出列的人是哪個?
PHP實現環形鏈表以及約瑟夫問題的解決:
/** * 鏈表結構 */ class Child{ public $no; public $next=null; public function __construct($no=null){ $this->no = $no; } } /** * 鏈表操作 */ class CycleLink{ private $nodeNum = 0; /** * 添加節點 */ public function addNode($head,$node) { $currentNode = $head; while ($currentNode->next!=null && $currentNode->next!=$head) { $currentNode = $currentNode->next; } $currentNode->next = $node; $currentNode->next->next = $head; $this->nodeNum++; } /** * 刪除節點 */ public function delNode($head,$no) { $currentNode = $head; while ($currentNode->next!=$head) { if($currentNode->next->no==$no){ $currentNode->next = $currentNode->next->next; $this->nodeNum--; break; } $currentNode = $currentNode->next; } } /** * 獲取節點數量 */ public function getNodeNum(){ return $this->nodeNum; } /** * 查找節點 */ public function findNode($head,$no){ $node = null; $currentNode = $head; while ($currentNode->next!=$head) { if($currentNode->next->no==$no){ $node = $currentNode->next; break; } $currentNode = $currentNode->next; } return $node; } public function getNextNode($head,$node){ if($node->next==$head){ return $node->next->next; } return $node->next; } /** * 顯示節點 */ public function showNode($head) { echo "<br/><br/>"; $currentNode = $head; while ($currentNode->next!=$head){ $currentNode = $currentNode->next; echo '第 '.$currentNode->no.' 名小孩<br/>'; } } } /* //創建一個head頭,該head 只是一個頭,不放入數據 $head = new Child(); $childList = new CycleLink(); $child_1 = new Child(1); $child_2 = new Child(2); $child_3 = new Child(3); $child_4 = new Child(4); $childList->addNode($head,$child_1); $childList->addNode($head,$child_2); $childList->addNode($head,$child_3); $childList->addNode($head,$child_4); $childList->showNode($head); echo "<pre>"; var_dump($head); $findNode = $childList->findNode($head,3); echo "<pre>"; var_dump($findNode); $childList->delNode($head,2); $childList->showNode($head); echo $childList->getNodeNum(); exit(); */ /** * 約瑟夫問題 * 設編號為1,2,...n的n個人圍坐一圈,約定編號為k(1<=k<=n)的人從1開始報數,數到m的那個人出列, * 它的下一位又從1開始報數,數到m的那個人又出列,依次類推,直到所有人出列為止,由此產生一個出隊編號的序列。 * 并求出最后出列的人是哪個? */ class Josephu{ private $head; private $childList; private $k; private $m; private $n; public function __construct($n,$k,$m){ $this->k = $k; $this->m = $m; $this->n = $n; $this->createList($n); // 創建小孩 echo "<br/><br/>當前有 {$n} 個小孩,從第 {$k} 個小孩開始報數,數到 {$m} 退出<br/><br/>"; } // 數數 public function exec(){ $currentNode = $this->childList->findNode($this->head,$this->k); // 獲取第一個開始報數的人 $_num = 0; // 當前數到的值 $surplus_num = $this->n; // 開始報數 while ($surplus_num>1) { // 只要人數大于1,就繼續報數 // 當前報數值 $_num++; $nextNode = $this->childList->getNextNode($this->head,$currentNode); // 數至第m個數,然后將其移除。報數恢復到0,重新循環。 if( $_num==$this->m ){ $_num = 0; $surplus_num--; // 當前小孩退出 $this->childList->delNode($this->head,$currentNode->no); echo '<br/>退出小孩編號:' . $currentNode->no; } // 移動到下一個小孩 $currentNode = $nextNode; } echo '<br/>最后一個小孩編號:' . $currentNode->no; } // 創建小孩 private function createList($n){ $this->childList = new CycleLink(); $this->head = new Child(); for ($i=1;$i<=$n;$i++){ $node = new Child($i); $this->childList->addNode($this->head,$node); } $this->childList->showNode($this->head); } } $josephu = new Josephu(4, 1, 2); $josephu->exec();
運行結果:
第 1 名小孩
第 2 名小孩
第 3 名小孩
第 4 名小孩
當前有 4 個小孩,從第 1 個小孩開始報數,數到 2 退出
上述內容就是怎么在php中使用環形鏈表解決約瑟夫問題,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。