• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    php使用环形链表解决约瑟夫问题完整示例

    本文实例讲述了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程序设计算法总结》、《php字符串(string)用法总结》、《PHP数组(Array)操作技巧大全》、《PHP常用遍历算法与技巧总结》及《PHP数学运算技巧总结》

    希望本文所述对大家PHP程序设计有所帮助。

    您可能感兴趣的文章:
    • PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
    • python环形单链表的约瑟夫问题详解
    • C语言基于循环链表解决约瑟夫环问题的方法示例
    • java基于双向环形链表解决丢手帕问题的方法示例
    • php基于环形链表解决约瑟夫环问题示例
    • Java编程删除链表中重复的节点问题解决思路及源码分享
    • C语言解字符串逆序和单向链表逆序问题的代码示例
    • Java采用循环链表结构求解约瑟夫问题
    • Leetcode常见链表问题及代码示例
    上一篇:postman的安装与使用方法(模拟Get和Post请求)
    下一篇:php实现往pdf中加数字签名操作示例【附源码下载】
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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