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 获取MSN好友列表的代码(2009-05-14测试通过)
Sep 09 PHP
ThinkPHP的Widget扩展实例
Jun 19 PHP
php选择排序法实现数组排序实例分析
Feb 16 PHP
PHP输入输出流学习笔记
May 12 PHP
php正则匹配文章中的远程图片地址并下载图片至本地
Sep 29 PHP
PHP开发中常用的十个代码样例
Feb 02 PHP
CodeIgniter框架基本增删改查操作示例
Mar 23 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
PHP实现的贪婪算法实例
Oct 17 PHP
php实现支付宝当面付(扫码支付)功能
May 30 PHP
php多进程模拟并发事务产生的问题小结
Dec 07 PHP
PHP中用Trait封装单例模式的实现
Dec 18 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
linux下安装php的memcached客户端
2014/08/03 PHP
yiic命令时提示“php.exe”不是内部或外部命令的解决方法
2014/12/18 PHP
Laravel的throttle中间件失效问题解决方法
2016/10/09 PHP
PHP基于curl模拟post提交json数据示例
2018/06/22 PHP
基于Laravel-admin 后台的自定义页面用法详解
2019/09/30 PHP
一些常用的JavaScript函数(json)附详细说明
2011/05/25 Javascript
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
js图片轮播效果实现代码
2020/04/18 Javascript
微信小程序 Flex布局详解
2016/10/09 Javascript
ES6新特性之Symbol类型用法分析
2017/03/31 Javascript
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
JavaScript基础教程之如何实现一个简单的promise
2018/09/11 Javascript
对angular 实时更新模板视图的方法$apply详解
2018/10/09 Javascript
vue中v-for通过动态绑定class实现触发效果
2018/12/06 Javascript
通过jQuery学习js类型判断的技巧
2019/05/27 jQuery
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
Vue文本模糊匹配功能如何实现
2020/07/30 Javascript
Python cookbook(数据结构与算法)对切片命名清除索引的方法
2018/03/13 Python
Python基于辗转相除法求解最大公约数的方法示例
2018/04/04 Python
python3 读写文件换行符的方法
2018/04/09 Python
pandas带有重复索引操作方法
2018/06/08 Python
python-str,list,set间的转换实例
2018/06/27 Python
Python基本socket通信控制操作示例
2019/01/30 Python
Python requests模块cookie实例解析
2020/04/14 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
使用CSS3制作一个简单的进度条(demo)
2017/05/23 HTML / CSS
html5使用canvas绘制文字特效
2014/12/15 HTML / CSS
网购亚洲时装、美容产品和生活百货:YesStyle
2016/09/15 全球购物
世界上最大的乐谱选择:Sheet Music Plus
2020/01/18 全球购物
linux面试题参考答案(10)
2013/11/04 面试题
大三在校生电子商务求职信
2013/10/29 职场文书
医学专业毕业生推荐信
2014/07/12 职场文书
道歉信怎么写
2015/05/12 职场文书