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();
?>
如有错误,敬请指正,虚心接受