php环形链表解决josephu问题
约瑟夫问题:n个小孩围成一圈,从第k个小孩开始数,没数到m的小孩出列。问最后剩下的是谁。
<?php
/**
* php环形链表解决josephu问题
*/
class child{
public $no;
public $next;
public function __construct($no){
$this->no = $no;
}
}
$first = null;
$n = 4;//表示有几个小朋友
$m = 3;
$k = 2;
/**
* addChild函数作用:把$n个小孩构建成一个环形链表,
* $first变量指向该环形链表的第一个小孩子。
*/
function addChild(&$first,$n){ //为什么加地址符
//1.头结点不能动
//内存 ;左堆右栈,中间 全局/静态,文字常量,代码 ;对象实例放在堆内,一般的变量放在栈内;值传递,对象传递,&引用传递。
$cur = null;
for($i=0;$i<$n;$i++){
$child = new child($i+1); //一个小朋友有也是环形
if($i==0){
$first = $child;
$first->next = $first;
$cur = $first;
}else{
$cur->next = $child;
$child->next = $first;
$cur = $cur->next;
}
}
}
/**
* 写一个函数显示圈中的小孩子 ,必须把$first给函数
*/
function showChild($first){
//遍历 $cur变量是帮助我们遍历环形链表,不能动。
$cur = $first;
while($cur->next!=$first){
echo "<br/>小孩的编号是".$cur->no;
$cur = $cur->next; //没有这句则死循环。
}
//当退出while循环时,cur指向了环形链表的最后节点,还要打印最后一个
echo "<br/>小孩的编号是".$cur->no;
}
//开始数数,问题简化,从第一个小孩开始数,数2,看出圈的顺序。
function countChild($first,$m,$k){
//思考:为了删除小孩,需要一个辅助变量,该变量指向的小孩在first前面;
$tail = $first;
while($tail->next!=$first){
$tail = $tail->next;
}
for($i=0;$i<$k-1;$i++){
$first = $first->next;
$tail= $tail->next;
}
//当退出while时,我们的$tail就指向了最后一个小孩
//没移动一下,相当于数了一下。移动两次相当于数了3次。
while($tail!=$first){ //当$tail==$first则说明只有最后一人了。
for($i=0;$i<$m-1;$i++){
$tail = $tail->next;
$first = $first->next;
}
$first = $first->next;
$tail->next = $first;
}
echo "<br/>最后留在圈圈中的人的编号是".$first->no;
}
header("Content-type:text/html; charset=utf-8");
addChild($first,$n);
showChild($first); //有问题吗? 只打印123个小孩
countChild($first,$m,$k);
?>
如果感觉不错,请
赞
一个!
by simpman
by simpman
浙公网安备 33010602011771号