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


Posted in PHP onAugust 07, 2018

本文实例讲述了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程序设计有所帮助。

PHP 相关文章推荐
Content-type 的说明
Oct 09 PHP
PHP用GD库生成高质量的缩略图片
Mar 09 PHP
解析mysql中UNIX_TIMESTAMP()函数与php中time()函数的区别
Jun 24 PHP
利用中国天气预报接口实现简单天气预报
Jan 20 PHP
destoon实现商铺管理主页设置增加新菜单的方法
Jun 26 PHP
PHP中mysql_field_type()函数用法
Nov 24 PHP
Windows下Apache + PHP SESSION丢失的解决过程全纪录
Apr 07 PHP
php实现简单的MVC框架实例
Sep 23 PHP
使用WordPress发送电子邮件的相关PHP函数用法解析
Dec 15 PHP
laravel 框架配置404等异常页面
Jan 07 PHP
PDO::getAvailableDrivers讲解
Jan 28 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
Mar 01 PHP
postman的安装与使用方法(模拟Get和Post请求)
Aug 06 #PHP
PHP实现的解汉诺塔问题算法示例
Aug 06 #PHP
PHP实现普通hash分布式算法简单示例
Aug 06 #PHP
PHP实现的无限分类类库定义与用法示例【基于thinkPHP】
Aug 06 #PHP
PHP常用字符串函数小结(推荐)
Aug 05 #PHP
PHP使用标准库spl实现的观察者模式示例
Aug 04 #PHP
PHP设计模式之观察者模式定义与用法示例
Aug 04 #PHP
You might like
php创建无限级树型菜单
2015/11/05 PHP
JavaScript中的Screen屏幕对象
2008/01/16 Javascript
CCPry JS类库 代码
2009/10/30 Javascript
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
9行javascript代码获取QQ群成员具体实现
2013/10/16 Javascript
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
2015/12/03 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
axios基本入门用法教程
2017/03/25 Javascript
Map.vue基于百度地图组件重构笔记分享
2017/04/17 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
2017/05/22 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
2017/10/25 Javascript
利用Console来Debug的10个高级技巧汇总
2018/03/26 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
2020/07/20 Javascript
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
2021/02/26 Vue.js
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
Python实现栈的方法
2015/05/26 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
python实现QQ批量登录功能
2019/06/19 Python
python3 线性回归验证方法
2019/07/09 Python
tensorflow estimator 使用hook实现finetune方式
2020/01/21 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
python 制作本地应用搜索工具
2021/02/27 Python
CSS3动画效果回调处理详解
2014/12/10 HTML / CSS
通过canvas转换颜色为RGBA格式及性能问题的解决
2019/11/22 HTML / CSS
人事档案接收函
2014/01/12 职场文书
数控专业大学毕业生职业规划范文
2014/02/06 职场文书
领导接待方案
2014/03/13 职场文书
奠基仪式策划方案
2014/05/15 职场文书
出纳工作检讨书
2014/10/18 职场文书
医院保洁员岗位职责
2015/02/13 职场文书
mysql字符串截取函数小结
2021/04/05 MySQL