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();
?>
如有錯誤,敬請指正,虛心接受