php使用環(huán)形鏈表解決約瑟夫問(wèn)題完整示例
本文實(shí)例講述了php使用環(huán)形鏈表解決約瑟夫問(wèn)題。分享給大家供大家參考,具體如下:
約瑟夫問(wèn)題:
Josephu問(wèn)題為:設(shè)編號(hào)為1,2,...n的n個(gè)人圍坐一圈,約定編號(hào)為k(1<=k<=n)的人從1開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人出列,它的下一位又從1開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人又出列,依次類(lèi)推,直到所有人出列為止,由此產(chǎn)生一個(gè)出隊(duì)編號(hào)的序列。并求出最后出列的人是哪個(gè)?
PHP實(shí)現(xiàn)環(huán)形鏈表以及約瑟夫問(wèn)題的解決:
/**
* 鏈表結(jié)構(gòu)
*/
class Child{
public $no;
public $next=null;
public function __construct($no=null){
$this->no = $no;
}
}
/**
* 鏈表操作
*/
class CycleLink{
private $nodeNum = 0;
/**
* 添加節(jié)點(diǎn)
*/
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++;
}
/**
* 刪除節(jié)點(diǎn)
*/
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;
}
}
/**
* 獲取節(jié)點(diǎn)數(shù)量
*/
public function getNodeNum(){
return $this->nodeNum;
}
/**
* 查找節(jié)點(diǎn)
*/
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;
}
/**
* 顯示節(jié)點(diǎn)
*/
public function showNode($head)
{
echo "<br/><br/>";
$currentNode = $head;
while ($currentNode->next!=$head){
$currentNode = $currentNode->next;
echo '第 '.$currentNode->no.' 名小孩<br/>';
}
}
}
/*
//創(chuàng)建一個(gè)head頭,該head 只是一個(gè)頭,不放入數(shù)據(jù)
$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();
*/
/**
* 約瑟夫問(wèn)題
* 設(shè)編號(hào)為1,2,...n的n個(gè)人圍坐一圈,約定編號(hào)為k(1<=k<=n)的人從1開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人出列,
* 它的下一位又從1開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人又出列,依次類(lèi)推,直到所有人出列為止,由此產(chǎn)生一個(gè)出隊(duì)編號(hào)的序列。
* 并求出最后出列的人是哪個(gè)?
*/
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); // 創(chuàng)建小孩
echo "<br/><br/>當(dāng)前有 {$n} 個(gè)小孩,從第 {$k} 個(gè)小孩開(kāi)始報(bào)數(shù),數(shù)到 {$m} 退出<br/><br/>";
}
// 數(shù)數(shù)
public function exec(){
$currentNode = $this->childList->findNode($this->head,$this->k); // 獲取第一個(gè)開(kāi)始報(bào)數(shù)的人
$_num = 0; // 當(dāng)前數(shù)到的值
$surplus_num = $this->n;
// 開(kāi)始報(bào)數(shù)
while ($surplus_num>1) { // 只要人數(shù)大于1,就繼續(xù)報(bào)數(shù)
// 當(dāng)前報(bào)數(shù)值
$_num++;
$nextNode = $this->childList->getNextNode($this->head,$currentNode);
// 數(shù)至第m個(gè)數(shù),然后將其移除。報(bào)數(shù)恢復(fù)到0,重新循環(huán)。
if( $_num==$this->m ){
$_num = 0;
$surplus_num--;
// 當(dāng)前小孩退出
$this->childList->delNode($this->head,$currentNode->no);
echo '<br/>退出小孩編號(hào):' . $currentNode->no;
}
// 移動(dòng)到下一個(gè)小孩
$currentNode = $nextNode;
}
echo '<br/>最后一個(gè)小孩編號(hào):' . $currentNode->no;
}
// 創(chuàng)建小孩
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();
運(yùn)行結(jié)果:
第 1 名小孩
第 2 名小孩
第 3 名小孩
第 4 名小孩
當(dāng)前有 4 個(gè)小孩,從第 1 個(gè)小孩開(kāi)始報(bào)數(shù),數(shù)到 2 退出
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《PHP數(shù)據(jù)結(jié)構(gòu)與算法教程》、《php程序設(shè)計(jì)算法總結(jié)》、《php字符串(string)用法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《PHP常用遍歷算法與技巧總結(jié)》及《PHP數(shù)學(xué)運(yùn)算技巧總結(jié)》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
- PHP+Redis鏈表解決高并發(fā)下商品超賣(mài)問(wèn)題(實(shí)現(xiàn)原理及步驟)
- python環(huán)形單鏈表的約瑟夫問(wèn)題詳解
- C語(yǔ)言基于循環(huán)鏈表解決約瑟夫環(huán)問(wèn)題的方法示例
- java基于雙向環(huán)形鏈表解決丟手帕問(wèn)題的方法示例
- php基于環(huán)形鏈表解決約瑟夫環(huán)問(wèn)題示例
- Java編程刪除鏈表中重復(fù)的節(jié)點(diǎn)問(wèn)題解決思路及源碼分享
- C語(yǔ)言解字符串逆序和單向鏈表逆序問(wèn)題的代碼示例
- Java采用循環(huán)鏈表結(jié)構(gòu)求解約瑟夫問(wèn)題
- Leetcode常見(jiàn)鏈表問(wèn)題及代碼示例
相關(guān)文章
PHP詳解ASCII碼對(duì)照表與字符轉(zhuǎn)換
PHP基礎(chǔ)篇詳解ASCII碼對(duì)照表與字符轉(zhuǎn)換,討論ASCII碼對(duì)照表圖與字符轉(zhuǎn)換為十進(jìn)制、八進(jìn)制、十六進(jìn)制和HTML的方法2011-12-12
php中通過(guò)DirectoryIterator刪除整個(gè)目錄的方法
這篇文章主要介紹了php中通過(guò)DirectoryIterator刪除整個(gè)目錄的方法,實(shí)例分析了php通過(guò)DirectoryIterator類(lèi)操作目錄的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
開(kāi)啟CURL擴(kuò)展,讓服務(wù)器支持PHP curl函數(shù)(遠(yuǎn)程采集)
關(guān)于開(kāi)啟Curl的方法模板天下小編在此給大家簡(jiǎn)單說(shuō)一下2011-03-03
php中文語(yǔ)義分析實(shí)現(xiàn)方法示例
這篇文章主要介紹了php中文語(yǔ)義分析實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了PHP基于BosonNLP擴(kuò)展實(shí)現(xiàn)中文語(yǔ)義分析的具體操作步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-09-09
PHP實(shí)現(xiàn)判斷二叉樹(shù)是否對(duì)稱(chēng)的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)判斷二叉樹(shù)是否對(duì)稱(chēng)的方法,涉及php遞歸二叉樹(shù)判斷節(jié)點(diǎn)的相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
php基于環(huán)形鏈表解決約瑟夫環(huán)問(wèn)題示例
這篇文章主要介紹了php基于環(huán)形鏈表解決約瑟夫環(huán)問(wèn)題,結(jié)合具體實(shí)例形式分析了php環(huán)形鏈表的定義及基于環(huán)形鏈表解決約瑟夫環(huán)的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11

