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 相关文章推荐
如何开发一个虚拟域名系统
Oct 09 PHP
php header Content-Type类型小结
Jul 03 PHP
用php解析html的实现代码
Aug 08 PHP
学习php过程中的一些注意点的总结
Oct 25 PHP
ThinkPHP3.1新特性之多数据库操作更加完善
Jun 19 PHP
Win7 64位系统下PHP连接Oracle数据库
Aug 20 PHP
Yii 快速,安全,专业的PHP框架
Sep 03 PHP
PHP框架Laravel的小技巧两则
Feb 10 PHP
Mac环境下php操作mysql数据库的方法分享
May 11 PHP
Zend Framework教程之路由功能Zend_Controller_Router详解
Mar 07 PHP
CI框架实现cookie登陆的方法详解
May 18 PHP
php中mkdir()函数的权限问题分析
Sep 24 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中redis的用法深入解析
2014/02/20 PHP
使用ob系列函数实现PHP网站页面静态化
2014/08/13 PHP
PHP实现简单汉字验证码
2015/07/28 PHP
ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
2018/07/30 PHP
js下将字符串当函数执行的方法
2011/07/13 Javascript
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
2011/07/31 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
js判断上传文件后缀名是否合法
2016/01/28 Javascript
jQuery ajax中使用confirm,确认是否删除的简单实例
2016/06/17 Javascript
gulp加批处理(.bat)实现ng多应用一键自动化构建
2017/02/16 Javascript
JavaScript实现分页效果
2017/03/28 Javascript
Angular2仿照微信UI实现9张图片上传和预览的示例代码
2017/10/19 Javascript
详解如何在React组件“外”使用父组件的Props
2018/01/12 Javascript
JS设计模式之状态模式概念与用法分析
2018/02/05 Javascript
JavaScript常用截取字符串的三种方式用法区别实例解析
2018/05/15 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
React.js组件实现拖拽排序组件功能过程解析
2020/04/27 Javascript
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
python实现监控linux性能及进程消耗性能的方法
2014/07/25 Python
详解Python中的文本处理
2015/04/11 Python
Django中login_required装饰器的深入介绍
2017/11/24 Python
python实现word 2007文档转换为pdf文件
2018/03/15 Python
python实现windows下文件备份脚本
2018/05/27 Python
pyqt5 QlistView列表显示的实现示例
2020/03/24 Python
浅谈keras使用中val_acc和acc值不同步的思考
2020/06/18 Python
Pedro官网:新加坡时尚品牌
2019/08/27 全球购物
索引覆盖(Index Covering)查询含义
2012/02/18 面试题
改革共识倡议书
2014/08/29 职场文书
护士医德医风自我评价
2014/09/15 职场文书
群众路线领导班子整改方案
2014/10/25 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
刑事附带民事诉讼答辩状
2015/05/22 职场文书
圣贤教育改变命运观后感
2015/06/16 职场文书
公司借款担保书
2015/09/22 职场文书
Python实现数据的序列化操作详解
2022/07/07 Python