1. 程式人生 > >php通過迴圈鏈解決約瑟夫環

php通過迴圈鏈解決約瑟夫環

本想著用php寫些資料結構提升一下,寫到鏈的時候看到約瑟夫環問題,嘗試用迴圈鏈寫了一下

約瑟夫環:

約瑟夫環(約瑟夫問題)是一個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列

程式碼:

<?php
header("Content-type: text/html; charset=utf-8");
/**
* 約瑟夫環
*/

/**
* 結點
*/
class Node {
  /*結點id*/
  public $id;
  /*結點資料域*/
  public $data;
  /*下一個結點的指標域*/
  public $_next;

  function __construct($data) {
    $this->id = null;
    $this->data = $data;
    $this->_next = null;
  }
}

/**
* 迴圈鏈 
*/
class CircularLinkedList {
  /*連結串列頭指標*/
  private $_header;

  /*連結串列尾指標*/
  private $_end;

  /*儲存連結串列資料的陣列*/
  private $data = array();

  function __construct($node) {
    $this->_header = 0;
    $this->_end = 0;
    $node->id = $this->_end;
    $node->_next = $this->_header;
    $this->data[$this->_end] = $node;
  }

  /*增加結點*/
  public function add_list($node) {
    $current = $this->data[$this->_header];
    while($current->_next !== $this->_header) {
      $current = $this->data[$current->_next];
    }

    $this->_end++;
    $node->id = $this->_end;
    $node->_next = $this->_header;
    $this->data[$current->id]->_next = $node->id;
    $this->data[$this->_end] = $node;
  }

  /*插入結點*/
  public function insert_list($where,$node) {
    if($where == 1){
      $current = $this->data[$this->_header];
      while($current->_next !== $this->_header) {
        $current = $this->data[$current->_next];
      }

      $this->_end++;
      $node->id = $this->_end;
      $node->_next = $this->data[$this->_header]->id;
      $this->data[$current->id]->_next = $node->id;
      $this->data[$this->_end] = $node;
      $this->_header = $node->id;
    }
    else{
      $current = $this->data[$this->_header];
      for($i=1;$i<$where-1;$i++) {
        $current = $this->data[$current->_next];
      }

      $this->_end++;
      $node->id = $this->_end;
      $node->_next = $this->data[$current->_next]->id;
      $this->data[$current->id]->_next = $node->id;
      $this->data[$this->_end] = $node;
    }
  }

/*刪除指定結點*/
public function del_list($where) {
  $current = $this->data[$this->_header];
  for($i=1;$i<$where-1;$i++) {
    $current = $this->data[$current->_next];
  }

  $next = $this->data[$current->id]->_next;

  if($where == 1) {
    $current_2 = $this->data[$this->_header];
    while($current_2->_next !== $this->_header) {
      $current_2 = $this->data[$current_2->_next];
    }

    $this->_header = $next;
    $this->data[$current_2->id]->_next = $next;
    unset($this->data[$current->id]);
  }
  else{
    $this->data[$current->id]->_next = $this->data[$next]->_next;
    unset($this->data[$next]);
  }
}

  /*迴圈鏈的長度*/
  public function get_length() {
    $current = $this->data[$this->_header];
    $length = 1;
    while($current->_next !== $this->_header) {
      $length ++;
      $current = $this->data[$current->_next];
    }

    return $length;
  }

  /*改變頭指標*/
  public function change_header($where) {
    $current = $this->search_node($where);

    $this->_header = $current->id;
  }

  /*查詢第n個結點*/
  public function search_node($where) {
    $current = $this->data[$this->_header];
    for($i=1;$i<$where;$i++) {
      $current = $this->data[$current->_next];
    }

    return $current;
  }

  public function set_header($header) {
    $this->_header = $header;
  }

  /*輸出迴圈鏈*/
  public function get_list() {
    $current = $this->data[$this->_header];
    while($current->_next !== $this->_header) {
      echo "[".$current->id."]".$current->data."--->";
      $current = $this->data[$current->_next];
    }
    echo "[".$current->id."]".$current->data."--->[".$this->data[$current->_next]->id."]".$this->data[$current->_next]->data;
    echo "<br>-----------------------------------------------<br>";
  }
}

/*約瑟夫環物件*/
class JosephCycle {

  /*迴圈鏈*/
  private $linkedlist;

  /*開始的位置*/
  private $_begin;

  /*開始到被踢出者的距離*/
  private $_distance;

  /**
  * 建構函式
  * @param object $linkedlist 迴圈鏈
  * @param int $begin 從第幾個開始
  * @param int $distance 從開始到被踢者的距離
  */
  function __construct($linkedlist,$begin,$distance) {
    $this->linkedlist = $linkedlist;
    $this->_begin = $begin;
    $this->_distance = $distance;
  }

  public function index() {
    $length = $this->linkedlist->get_length();
    $this->linkedlist->change_header($this->_begin);
    for($i=1;$i<$length;$i++) {
      $node = $this->linkedlist->search_node($this->_distance);
      $this->linkedlist->del_list($this->_distance);
      $this->linkedlist->set_header($node->_next);
      $this->linkedlist->get_list();
    }
  }
}

$list = new CircularLinkedList(new Node("測試1"));
$list->add_list(new Node("測試2"));
$list->add_list(new Node("測試3"));
$list->add_list(new Node("測試4"));
$list->add_list(new Node("測試5"));
$list->add_list(new Node("測試6"));
$list->add_list(new Node("測試7"));
$list->add_list(new Node("測試8"));
$list->add_list(new Node("測試9"));
$list->add_list(new Node("測試10"));
$list->add_list(new Node("測試11"));
$list->add_list(new Node("測試12"));
$list->add_list(new Node("測試13"));
$list->get_list();

$solution = new JosephCycle($list,6,8);
$solution->index();
?>

如有錯誤,敬請指正,虛心接受