PHP实现简单双向链表

用PHP实现双向链表,在实现上,与C++的区别,主要在指针与this的使用上的不同。在数据结构方面双向链表要考虑两个方向四个指向,每次增减节点时注意每个指向都要照顾到。
实现文件DoubleLinkList.php

<?php
/**
 * **双向链表
 * @author [email protected]
 *
 */

 /**
 * 链表元素结点类
 */
class Node{
    public $prev = NULL; // 前驱
    public $next = NULL; // 后继
    public $key = NULL; // 元素键值
    public $data = NULL; // 结点值

    function __Construct($key, $data) {
        $this->key = $key;
        $this->data = $data;
    }
}

class DoubleLinkList{
    private $head;
    private $tail;
    private $current;
    private $size;

    function __Construct(){
        $this->head = $this->tail = NULL;
        $this->size = 0;
    }

    /**
     * 在链表头部加入节点
     * @param $key 要插入元素的key
     * @param $data 要插入链表元素的数据
     */
    public function addFirst($key, $data){
        $newNode = new Node($key, $data);
        $newNode->next = $this->head;
        $this->head->prev->next = $newNode;
        $this->head->prev = $newNode;
        $this->head = $newNode;
        $this->size++;

        if($this->tail === NULL){
            $this->tail = $this->head;
        }
    }

    /**
     * 在链表尾部加入节点
     * @param $key 要插入元素的key
     * @param $data 要插入链表元素的数据
     */
    public function addLast($key, $data){
        if($this->tail === NULL){
            $this->addFirst($key, $data);
        }else{
            $newNode = new Node($key, $data);
            $newNode->prev = $this->tail;
            $this->tail->next->prev = $newNode;
            $this->tail->next = $newNode;
            $this->tail = $newNode;
        }
        $this->size++;
    }

    /**
     * 删除链表头部节点
     */
    public function removeFirst(){
        if($this->size == 0){
            throw new Exception("The list is empty");
        } else {
            $tmp = $this->head;
            $this->head = $tmp->next;
            $this->head->prev = $tmp->prev;
            if($this->head === NULL) $this->tail = NULL;
            unset($tmp);
            $this->size--;
        }
    }

    /**
     * 删除链表尾部节点
     */
    public function removeLast(){
        if($this->size == 0){
            throw new Exception("The list is empty");
        } else {
            $tmp = $this->tail;
            $this->tail = $tmp->prev;
            $this->tail->next = $tmp->next;
            if($this->tail === NULL) $this->head = NULL;
            unset($tmp);
            $this->size--;
        }
    }

    /**
     * 获得头部节点的数据
     * @throws 链表为空
     */
     public function getFirst(){
         if($this->size == 0){
             throw new Exception("The list is empty");
         } else {
             var_dump($this->head->key, $this->head->data);
         }
     }

     /**
      * 获得尾部节点的数据
      * @throws 链表为空
      */
      public function getLast(){
          if($this->size == 0){
              throw new Exception("The list is empty");
          } else {
              var_dump($this->tail->key, $this->tail->data);
          }
      }

      /**
      * 在指定位置插入节点
      * @param $pos 指定元素在列表的位置
      * @param $key 要插入元素的key
      * @param $data 要插入链表元素的数据
      */
      public function add($pos, $key, $data){
          if($pos == 0){
              $this->addFirst($key, $data);
          }else if($pos >= $this->size){
              $this->addLast($key, $data);
          }else{
              $this->current = $this->head;
              for($i = 1; $i < $pos; $i++){
                  $this->current = $this->current->next;
              }
              $tmp = $this->current->next;
              $newNode = new Node($key, $data);
              $newNode->next = $tmp;
              $newNode->prev = $this->current;
              $this->current->next = $newNode;
              $tmp->prev = $newNode;
              $this->size++;
          }
      }


      /**
      * 在指定位置删除节点
      * @param $pos 指定元素在列表的位置
      * @param $key 要插入元素的key
      * @param $data 要插入链表元素的数据
      */
      public function remove($pos){
          if($pos == 0){
              $this->removeFirst();
          }else if($pos >= $this->size){
              $this->removeLast();
          }else{
              $this->current = $this->head;
              for($i = 1; $i < $pos; $i++){
                  $this->current = $this->current->next;
              }
              $tmp = $this->current->next;
              $this->current->next = $tmp->next;
              $tmp->next->prev = $this->current;
              $this->size--;
          }
      }

     /**
      * 获得所有节点的数据
      * @throws 链表为空
      */
      public function getAll(){
          if($this->size == 0){
              throw Exception("The list is empty");
          } else {
              $tmp = $this->head;
              while($tmp !== NULL){
                  var_dump($tmp->key, $tmp->data);
                  $tmp = $tmp->next;
              }
          }
      }

      /**
      * 根据key获得指定节点的数据
      * @param $key 指定的key值
      * @return $data 对应的数据
      */
      public function findByKey($key){
          $tmp = $this->head;
          while ($tmp !== NULL) {
              if ($tmp->key === $key) {
                  return $tmp->data;
              }
              $tmp = $tmp->next;
          }
          return null;
      }

      /**
      * 根据pos获得指定节点的数据
      * @param $pos 指定的key值
      * @return $tmp 对应的key和data数据
      */
      public function findByPos($pos){
          if ($pos <= 0 || $pos > $this->size)
            return null;
        if ($pos < ($this->size / 2 + 1)) {
            $tmp = $this->head;
            $count = 0;
            while ( $tmp->next !== null ) {
                $tmp = $tmp->next;
                $count++;
                if ($count === $pos) {
                    return $tmp;
                }
            }
        } else {
            $tmp = $this->tail;
            $pos = $this->size - $pos + 1;
            $count = 1;
            while ( $tmp->prev !== null ) {
                if ($count === $pos) {
                    return $tmp;
                }
                $tmp = $tmp->pre;
                $count++;
            }
        }
        return null;
      }

      /**
      * 清空链表
      */
      public function clear(){
          while($this->head !== NULL){
              $tmp = $this->head;
              $this->head = $this->head->next;
              unset($tmp);
          }
      }
}

测试文件

<?php
include "./DoubleLinkList.php";

$list = new DoubleLinkList();
$list->addFirst(1, "orange");
$list->addLast(2, "apple");
$list->addLast(3, "banana");
$list->addFirst(4, "grape");
$list->getFirst();
$list->removeFirst();
$list->getLast();
echo "-----------------";
$list->getAll();
echo "-----------------";
$list->removeLast();
$list->getAll();
echo "-----------------";
$list->add(1, 4, "peal");
$list->getAll();
echo "-----------------";
$list->add(1, 5, "watermoon");
$list->addFirst(6, "strawberry");
$list->remove(3);
$list->getAll();
echo "-----------------";
var_dump($list->findByKey(2));
echo "-----------------";
$a = $list->findByPos(2);
var_dump($a->key, $a->data);
echo "-----------------";
$list->clear();
$list->getAll();

猜你喜欢

转载自blog.csdn.net/intersting/article/details/60982233