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 相关文章推荐
PHP 5.0对象模型深度探索之绑定
Sep 05 PHP
用文本文件制作留言板提示(下)
Oct 09 PHP
用PHP程序实现支持页面后退的两种方法
Jun 30 PHP
PHP对象Object的概念 介绍
Jun 14 PHP
深入apache配置文件httpd.conf的部分参数说明
Jun 28 PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
Oct 16 PHP
php cookie中点号(句号)自动转为下划线问题
Oct 21 PHP
php继承中方法重载(覆盖)的应用场合
Feb 09 PHP
什么是PEAR?什么是PECL?PHP中两个容易混淆的概念解释
Jul 01 PHP
Laravel框架自定义公共函数的引入操作示例
Apr 16 PHP
php计数排序算法的实现代码(附四个实例代码)
Mar 31 PHP
浅析PHP echo 和 print 语句
Jun 30 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/05/27 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
javascript据option的value值快速设定初始的selected选项
2007/08/13 Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
2011/07/22 Javascript
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
JavaScript+CSS实现仿天猫侧边网页菜单效果
2015/08/25 Javascript
基于jquery编写的放大镜插件
2016/03/23 Javascript
jQuery链式调用与show知识浅析
2016/05/11 Javascript
AngularJS 执行流程详细介绍
2016/08/18 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
2018/09/28 Javascript
微信小程序显示倒计时功能示例【测试可用】
2018/12/03 Javascript
js实现图片上传即时显示效果
2019/09/30 Javascript
javascript实现简易计算器功能
2020/09/23 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
python实现对一个完整url进行分割的方法
2015/04/29 Python
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
2015/10/18 Python
Python即时网络爬虫项目启动说明详解
2018/02/23 Python
用Python3创建httpServer的简单方法
2018/06/04 Python
Windows下python3.6.4安装教程
2018/07/31 Python
python3 enum模块的应用实例详解
2019/08/12 Python
python 字典访问的三种方法小结
2019/12/05 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
使用css3实现的tab选项卡代码分享
2014/12/09 HTML / CSS
Html+Css+Jquery实现左侧滑动拉伸导航菜单栏的示例代码
2020/03/17 HTML / CSS
酒店工作职员求职简历的自我评价
2013/10/23 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
2014年军人思想汇报范文
2014/10/12 职场文书
个人查摆问题自查报告
2014/10/16 职场文书
医院营销工作计划
2015/01/16 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
解析:创业计划书和商业计划书二者之间到底有什么区别
2019/08/14 职场文书
关于MybatisPlus配置双数据库驱动连接数据库问题
2022/01/22 Java/Android
关于MySQL临时表为什么可以重名的问题
2022/03/22 MySQL