约瑟夫环环形链表java_php使用环形链表解决约瑟夫问题完整示例

本文实例讲述了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 "
";

$currentNode = $head;

while ($currentNode->next!=$head){

$currentNode = $currentNode->next;

echo '第 '.$currentNode->no.' 名小孩
';

}

}

}

/*

//创建一个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 "

";

var_dump($head);

$findNode = $childList->findNode($head,3);

echo "

";

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 "
当前有 {$n} 个小孩,从第 {$k} 个小孩开始报数,数到 {$m} 退出
";

}

// 数数

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 '
退出小孩编号:' . $currentNode->no;

}

// 移动到下一个小孩

$currentNode = $nextNode;

}

echo '
最后一个小孩编号:' . $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程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值