<?php /** * Created by PhpStorm. * User: dongdong * Date: 2015/3/26 * Time: 10:01 */ class LinkNode{ public $pre=null; public $next=null; public $key; public $data; public function __construct($key,$data){ $this->key = $key; $this->data = $data; } } class DoubleLink implements Countable,Iterator { private $head; // 头指针 private $tail; // 尾指针 private $current; // 当前指针 private $len; // 链表长度 public function __construct(){ $this->head = new LinkNode(null,null); $this->current = $this->head; $this->tail = $this->head; $this->len =0; } public static function newNode($key,$data){ if(empty($key)){ throw new Exception('键值不能为空'); } return new LinkNode($key,$data); } public function add($key,$data){ if(!is_null($this->find($key))){ throw new Exception("键值已存在"); } $node = self::newNode($key,$data); $this->tail->next = $node; $node->pre = $this->tail; $this->tail = $node; $this->len++; return $this; } public function insert($pos,$key,$data){ $cur = $this->find($pos); if(is_null($cur)){ throw new Exception('您要插入的位置不存在'); } $node = self::newNode($key,$data); if(is_null($cur->next)){ $this->tail = $node; $cur->next = $node; $node->pre = $cur; }else{ $oldNext = $cur->next; $cur->next = $node; $node->next = $oldNext; } $this->len++; return $this; } public function remove($key){ $cur = $this->find($key); if(is_null($cur)){ throw new Exception('链表中不存在该键值'); } $pre = $cur->pre; if(is_null($cur->next)){ $this->tail = $pre; }else{ $next = $cur->next; $pre->next = $next; $next->pre = $pre; } unset($cur); $this->len--; return $this; } public function find($key){ $cur = $this->head; while(!is_null($cur->next)){ $cur = $cur->next; if($cur->key == $key){ return $cur; } } return null; } public function toArray(){ if($this->len <= 0){ return null; } $cur = $this->head; while(!is_null($cur->next)){ $cur = $cur->next; $a[$cur->key] = $cur->data; } return $a; } public function getTail(){ return $this->tail; } /** * (PHP 5 >= 5.1.0)<br/> * Count elements of an object * @link http://php.net/manual/en/countable.count.php * @return int The custom count as an integer. * </p> * <p> * The return value is cast to an integer. */ public function count() { return $this->len; } /** * (PHP 5 >= 5.0.0)<br/> * Return the current element * @link http://php.net/manual/en/iterator.current.php * @return mixed Can return any type. */ public function current() { return $this->current->data; } /** * (PHP 5 >= 5.0.0)<br/> * Move forward to next element * @link http://php.net/manual/en/iterator.next.php * @return void Any returned value is ignored. */ public function next() { $this->current = $this->current->next; } /** * (PHP 5 >= 5.0.0)<br/> * Return the key of the current element * @link http://php.net/manual/en/iterator.key.php * @return mixed scalar on success, or null on failure. */ public function key() { return $this->current->key; } /** * (PHP 5 >= 5.0.0)<br/> * Checks if current position is valid * @link http://php.net/manual/en/iterator.valid.php * @return boolean The return value will be casted to boolean and then evaluated. * Returns true on success or false on failure. */ public function valid() { return $this->len > 0 && !is_null($this->current); } /** * (PHP 5 >= 5.0.0)<br/> * Rewind the Iterator to the first element * @link http://php.net/manual/en/iterator.rewind.php * @return void Any returned value is ignored. */ public function rewind() { $this->current = $this->head->next; } } header('Content-Type:text/html;charset=utf-8'); $dl = new DoubleLink(); for($i=1;$i<=10;$i++){ $dl->add($i,'a'.$i); } foreach($dl as $key=>$val){ var_dump( $val ); }echo "<br />当前链表顺序:"; print_r($dl->toArray()); echo "<br />"; echo "输出当前尾节点的值:"; echo $dl->getTail()->data; echo "<br >"; echo "输出键值为4的值:"; echo $dl->find(4)->data; echo "<br >"; echo "删除键值为4的节点"; $dl->remove(4); echo "<br>当前链表"; print_r($dl->toArray()); echo "<br>往键值为8的节点后面插入一个新的节点"; $dl->insert(8,99,'999999'); echo "<br>当前链表"; print_r($dl->toArray()); echo "<br>往键值为10的节点后面插入一个新的节点"; $dl->insert(10,12,'1212121212'); echo "<br>当前链表"; print_r($dl->toArray()); echo "<br />"; echo "输出当前尾节点的值:"; echo $dl->getTail()->data;