PHP双向链表定义与用法示例


Posted in PHP onJanuary 31, 2018

本文实例讲述了PHP双向链表定义与用法。分享给大家供大家参考,具体如下:

由于需要对一组数据多次进行移动操作,所以写个双向链表。但对php实在不熟悉,虽然测试各个方法没啥问题,就是不知道php语言深层的这些指针和unset有什么注意的地方,贴出来让大家教育吧。效率没测试....求谅解~

<?php
/**
 * **双向链表
 * @author zhiyuan12@
 */
/**
 * 链表元素结点类
 */
class Node_Element {
  public $pre = NULL; // 前驱
  public $next = NULL; // 后继
  public $key = NULL; // 元素键值
  public $data = NULL; // 结点值
  function __Construct($key, $data) {
    $this->key = $key;
    $this->data = $data;
  }
}
/**
 * 双向链表类
 */
class DoubleLinkedList {
  private $head; // 头指针
  private $tail; // 尾指针
  private $current; // 当前指针
  private $len; // 链表长度
  function __Construct() {
    $this->head = self::_getNode ( null, null );
    $this->curelement = $this->head;
    $this->tail = $this->head;
    $len = 0;
  }
  /**
   * @ desc: 读取链表全部结点
   */
  public function readAll() {
    $tmp = $this->head;
    while ( $tmp->next !== null ) {
      $tmp = $tmp->next;
      var_dump ( $tmp->key, $tmp->data );
    }
  }
  public function move($pos1, $pos2) {
    $pos1Node = $this->findPosition ( $pos1 );
    $pos2Node = $this->findPosition ( $pos2 );
    if ($pos1Node !== null && $pos2Node !== null) {
      $tmpKey = $pos1Node->key;
      $tmpData = $pos1Node->data;
      $pos1Node->key = $pos2Node->key;
      $pos1Node->data = $pos2Node->data;
      $pos2Node->key = $tmpKey;
      $pos2Node->data = $tmpData;
      return true;
    }
    return false;
  }
  /**
   * @ desc: 在指定关键词删除结点
   *
   * @param : $key
   *     指定位置的链表元素key
   */
  public function delete($key) {
    $pos = $this->find ( $key );
    if ($pos !== null) {
      $tmp = $pos;
      $last = null;
      $first = true;
      while ( $tmp->next !== null && $tmp->next->key === $key ) {
        $tmp = $tmp->next;
        if (! $first) {
          $this->delNode ( $last );
        } else {
          $first = false;
        }
        $last = $tmp;
      }
      if ($tmp->next !== null) {
        $pos->pre->next = $tmp->next;
        $tmp->next->pre = $pos->pre;
      } else {
        $pos->pre->next = null;
      }
      $this->delNode ( $pos );
      $this->delNode ( $tmp );
    }
  }
  /**
   * @ desc: 在指定位置删除结点
   *
   * @param : $key
   *     指定位置的链表元素key
   */
  public function deletePosition($pos) {
    $tmp = $this->findPosition ( $pos );
    if ($tmp === null) {
      return true;
    }
    if ($tmp === $this->getTail ()) {
      $tmp->pre->next = null;
      $this->delNode ( $tmp );
      return true;
    }
    $tmp->pre->next = $tmp->next;
    $tmp->next->pre = $tmp->pre;
    $this->delNode ( $tmp );
  }
  /**
   * @ desc: 在指定键值之前插入结点
   *
   * @param : $key
   *     //指定位置的链表元素key
   * @param : $data
   *     //要插入的链表元素数据
   * @param : $flag
   *     //是否顺序查找位置进行插入
   */
  public function insert($key, $data, $flag = true) {
    $newNode = self::_getNode ( $key, $data );
    $tmp = $this->find ( $key, $flag );
    if ($tmp !== null) {
      $newNode->pre = $tmp->pre;
      $newNode->next = $tmp;
      $tmp->pre = $newNode;
      $newNode->pre->next = $newNode;
    } else {
      $newNode->pre = $this->tail;
      $this->tail->next = $newNode;
      $this->tail = $newNode;
    }
    $this->len ++;
  }
  /**
   * @ desc: 在指定位置之前插入结点
   *
   * @param : $pos
   *     指定插入链表的位置
   * @param : $key
   *     指定位置的链表元素key
   * @param : $data
   *     要插入的链表元素数据
   */
  public function insertPosition($pos, $key, $data) {
    $newNode = self::_getNode ( $key, $data );
    $tmp = $this->findPosition ( $pos );
    if ($tmp !== null) {
      $newNode->pre = $tmp->pre;
      $newNode->next = $tmp;
      $tmp->pre = $newNode;
      $newNode->pre->next = $newNode;
    } else {
      $newNode->pre = $this->tail;
      $this->tail->next = $newNode;
      $this->tail = $newNode;
    }
    $this->len ++;
    return true;
  }
  /**
   * @ desc: 根据key值查询指定位置数据
   *
   * @param : $key
   *     //指定位置的链表元素key
   * @param : $flag
   *     //是否顺序查找
   */
  public function find($key, $flag = true) {
    if ($flag) {
      $tmp = $this->head;
      while ( $tmp->next !== null ) {
        $tmp = $tmp->next;
        if ($tmp->key === $key) {
          return $tmp;
        }
      }
    } else {
      $tmp = $this->getTail ();
      while ( $tmp->pre !== null ) {
        if ($tmp->key === $key) {
          return $tmp;
        }
        $tmp = $tmp->pre;
      }
    }
    return null;
  }
  /**
   * @ desc: 根据位置查询指定位置数据
   *
   * @param : $pos
   *     //指定位置的链表元素key
   */
  public function findPosition($pos) {
    if ($pos <= 0 || $pos > $this->len)
      return null;
    if ($pos < ($this->len / 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->len - $pos + 1;
      $count = 1;
      while ( $tmp->pre !== null ) {
        if ($count === $pos) {
          return $tmp;
        }
        $tmp = $tmp->pre;
        $count ++;
      }
    }
    return null;
  }
  /**
   * @ desc: 返回链表头节点
   */
  public function getHead() {
    return $this->head->next;
  }
  /**
   * @ desc: 返回链表尾节点
   */
  public function getTail() {
    return $this->tail;
  }
  /**
   * @ desc: 查询链表节点个数
   */
  public function getLength() {
    return $this->len;
  }
  private static function _getNode($key, $data) {
    $newNode = new Node_Element ( $key, $data );
    if ($newNode === null) {
      echo "new node fail!";
    }
    return $newNode;
  }
  private function delNode($node) {
    unset ( $node );
    $this->len --;
  }
}
$myList = new DoubleLinkedList ();
$myList->insert ( 1, "test1" );
$myList->insert ( 2, "test2" );
$myList->insert ( "2b", "test2-b" );
$myList->insert ( 2, "test2-c" );
$myList->insert ( 3, "test3" );
$myList->insertPosition ( 5, "t", "testt" );
$myList->readAll ();
echo "+++";
$myList->deletePosition(0);
$myList->readAll ();
echo "..." . $myList->getLength ();
var_dump ( $myList->findPosition ( 3 )->data );
?>

运行结果:

int(1)
string(5) "test1"
int(2)
string(7) "test2-c"
int(2)
string(5) "test2"
string(2) "2b"
string(7) "test2-b"
string(1) "t"
string(5) "testt"
int(3)
string(5) "test3"
+++int(1)
string(5) "test1"
int(2)
string(7) "test2-c"
int(2)
string(5) "test2"
string(2) "2b"
string(7) "test2-b"
string(1) "t"
string(5) "testt"
int(3)
string(5) "test3"
...6string(5) "test2"

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
利用php来自动调用不同服务器上的flash
Oct 09 PHP
PHP 写文本日志实现代码
May 18 PHP
在PHP中使用curl_init函数的说明
Nov 02 PHP
linux iconv方法的使用
Oct 01 PHP
PHP递归返回值时出现的问题解决办法
Feb 19 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
Jun 03 PHP
php5.3 注意事项说明
Jul 01 PHP
thinkphp实现like模糊查询实例
Oct 29 PHP
php基础教程
Aug 26 PHP
php实现微信公众平台账号自定义菜单类
Oct 11 PHP
PHP 文件锁与进程锁的使用示例
Aug 07 PHP
PHP单元测试配置与使用方法详解
Dec 27 PHP
基于PHP实现的多元线性回归模拟曲线算法
Jan 30 #PHP
PHP 记录访客的浏览信息方法
Jan 29 #PHP
laravel ORM 只开启created_at的几种方法总结
Jan 29 #PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
Jan 29 #PHP
PHP 使用二进制保存用户状态的实例
Jan 29 #PHP
thinkphp3.2.0 setInc方法 源码全面解析
Jan 29 #PHP
Ubuntu上安装yaf扩展的方法
Jan 29 #PHP
You might like
php+xml编程之SimpleXML的应用实例
2015/01/24 PHP
PHP常用的排序和查找算法
2015/08/06 PHP
PHP单例模式与工厂模式详解
2017/08/29 PHP
php web环境和命令行环境下查找php.ini的位置
2019/07/17 PHP
PHP实现简单的协程任务调度demo示例
2020/02/01 PHP
javascript函数库-集合框架
2007/04/27 Javascript
javascript 一个函数对同一元素的多个事件响应
2009/07/25 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
jQuery响应鼠标事件并隐藏与显示input默认值
2014/08/24 Javascript
jQuery实现精美的多级下拉菜单特效
2015/03/14 Javascript
使用javascript插入样式
2016/03/14 Javascript
JavaScript生成带有缩进的表格代码
2016/06/15 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
Vue2单一事件管理组件通信
2017/05/09 Javascript
理解 javascript 中的函数表达式与函数声明
2017/07/07 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
微信小程序提取公用函数到util.js及使用方法示例
2019/01/10 Javascript
vue实现带过渡效果的下拉菜单功能
2020/02/19 Javascript
Python标准库os.path包、glob包使用实例
2014/11/25 Python
python实现猜拳小游戏
2020/04/05 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
解决Keras TensorFlow 混编中 trainable=False设置无效问题
2020/06/28 Python
解决Python 函数声明先后顺序出现的问题
2020/09/02 Python
python更新数据库中某个字段的数据(方法详解)
2020/11/18 Python
HTML5 canvas画矩形时出现边框样式不一致的解决方法
2013/10/14 HTML / CSS
HTML5新特性之用SVG绘制微信logo
2016/02/03 HTML / CSS
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
中东最大的在线宠物店:Dubai Pet Food
2020/06/11 全球购物
保护环境演讲稿
2014/05/10 职场文书
企业文明单位申报材料
2014/05/16 职场文书
电气自动化求职信
2014/06/24 职场文书
幸福中国演讲稿
2014/09/12 职场文书
2015年助残日活动总结
2015/03/27 职场文书
工作调动申请报告
2015/05/18 职场文书
教师见习总结范文
2015/06/23 职场文书
PHP获取学生成绩的方法
2021/11/17 PHP