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实现Ftp用户的在线管理的代码
Mar 06 PHP
PHP+MySQL 制作简单的留言本
Nov 02 PHP
基于curl数据采集之正则处理函数get_matches的使用
Apr 28 PHP
php计算数组不为空元素个数的方法
Jan 27 PHP
php关键字仅替换一次的实现函数
Oct 29 PHP
WordPress网站性能优化指南
Nov 18 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
Aug 18 PHP
php实现数组中出现次数超过一半的数字的统计方法
Oct 14 PHP
PHP中Static(静态)关键字功能与用法实例分析
Apr 05 PHP
Laravel 自带的Auth验证登录方法
Sep 30 PHP
Yii 实现数据加密和解密
Mar 09 PHP
PHP中国际化的字符串排序和比较对象详解
Aug 23 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 动态随机生成验证码类代码
2010/04/09 PHP
合并ThinkPHP配置文件以消除代码冗余的实现方法
2014/07/22 PHP
php实现搜索类封装示例
2016/03/31 PHP
jquery 元素控制(追加元素/追加内容)介绍及应用
2013/04/21 Javascript
js图片自动切换效果处理代码
2013/05/07 Javascript
js 获取radio按钮值的实例
2013/08/17 Javascript
jQuery功能函数详解
2015/02/01 Javascript
jQuery中toggle()函数的使用实例
2015/04/17 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
canvas学习之API整理笔记(一)
2016/12/29 Javascript
前端构建工具之gulp的语法教程
2017/06/12 Javascript
AngularJS点击添加样式、点击变色设置的实例代码
2017/07/27 Javascript
深入了解js原型模式
2019/05/30 Javascript
python实现带声音的摩斯码翻译实现方法
2015/05/20 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
Vue的el-scrollbar实现自定义滚动
2018/05/29 Python
对Python 获取类的成员变量及临时变量的方法详解
2019/01/22 Python
Appium+Python自动化测试之运行App程序示例
2019/01/23 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
pytorch 自定义卷积核进行卷积操作方式
2019/12/30 Python
CSS3属性使网站设计增强同时不消弱可用性
2009/08/29 HTML / CSS
HTML5 SEO优化的一些建议
2020/08/27 HTML / CSS
提供世界各地便宜的机票:Sky-tours
2016/07/21 全球购物
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
戴尔新西兰官网:Dell New Zealand
2020/01/07 全球购物
什么是唯一索引
2015/07/05 面试题
销售经理工作职责范文
2013/12/03 职场文书
市场部业务员岗位职责
2014/04/02 职场文书
仓库文员岗位职责
2014/04/06 职场文书
公司联欢会策划方案
2014/05/19 职场文书
2014县政府领导班子对照检查材料思想汇报
2014/09/25 职场文书
个人四风问题整改措施思想汇报
2014/10/04 职场文书
检讨书1000字
2014/10/11 职场文书
2014年第四季度入党积极分子思想汇报(十八届四中全会)
2014/11/03 职场文书
Java 超详细讲解ThreadLocal类的使用
2022/04/07 Java/Android