PHP实现简单双向链表

php数据结构一:链表之双向链表 之前我们已看过php中链表的概念及单向链表(php数据结构一:链表之单向链表),今天我们来看链表的第二种类型——双向链表。 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。 双向链表图解: php实现双向链表 ... 阅读详情

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

<?php
/**
 * **双向链表
 * @author tju_zyt@tju.edu.cn
 *
 */

 /**
 * 链表元素结点类
 */
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();
PHP实现double linked list双向链表的算法(附完整源码) 阅读详情

相关推荐

ADS 使用教程(十八)Encrypting Designs using RFIP Encoder in ADS

在这一节,我们使用RFIP Encoder进行设计加密,这是一种保护知识产权和敏感设计数据的重要方法。RFIP Encoder提供了一种安全的方式来加密设计文件,确保只有授权人员能够访问和使用这些文件。

Dirge19的博客 1169

php实现双向链表(LinkedList)

PHP实现Java集合之双向链表(LinkedList)

iflycc的博客 858

flink定位反压节点

在 Apache Flink 中定位反压(Backpressure)节点需要结合监控工具和作业行为分析。

2301_80954266的博客 1045

数据结构——双链表详解(超详细)

哨兵位这个名字看起来是很威武的,其实了解它之后就知道它仅仅就是名字威武点,它才是真正意义上的头结点,哨兵位是不存数据的,它的存在仅仅就是为了说明这个链表是带头的,是用来“放哨的”,小编在讲述单链表的时候曾多次提到了头结点这个名字,那个时候头结点是链表第一个结点,这个叫法是不太规范的,不过为了让读者朋友更好的去理解链表的知识,小编于是就直接头结点来代替链表第一个结点了,不过各位读者朋友一定要清楚。下面紧跟小编的步伐,开启今天的双链表之旅!

effort123_的博客 1624

细节增强卷积DEConv详解及代码复现

这种预训练模型能够捕捉图像的基本特征,为后续的端到端训练提供良好的初始参数。例如,在RESIDE和RESIDE-6K数据集上的实验结果表明,使用MSPLCK模块的MixDehazeNet-L模型在RESIDE-IN数据集上首次超过了42dB的PSNR指标,且在所有数据集上均优于先前的方法。例如,在RESIDE和RESIDE-6K数据集上的实验结果表明,使用MSPLCK模块的MixDehazeNet-L模型在RESIDE-IN数据集上首次超过了42dB的PSNR指标,且在所有数据集上均优于先前的方法。

hasakie的博客 1909

Keil5 安装与卸载全攻略:从零开始到完美避坑

本文提供了Keil5集成开发环境的完整安装与卸载指南。针对嵌入式开发新手,详细解析了安装前的关键准备、MDK核心与C51双环境的安装激活步骤、常见问题排查,并重点介绍了如何彻底卸载软件以避免残留问题,帮助用户从零开始搭建稳定高效的开发环境。

weixin_29172963的博客 636

双向链表php,画江湖之数据结构 [第一话:链表] 双向链表

链表1 双链表概括:双向链表有两个引用分别指向前后节点。优势方便向前查询数据。请看上图:data为数据,pre为指向前个节点的引用,next为指向后个节点的引用 。完整代码块:/*** 节点实现*/class Node{/*** 数据元素* @var*/public $item;/*** 前驱节点* @var*/public $prev;/*** 后继节点* @var*/public $next;...

weixin_29963537的博客 111

音视频入门:H264、H265概念总结

添加链接描述 什么是H.264与H.265 H.264与H.265都是视频压缩格式,由于视频本身的码流太大,所以需要经过压缩然后再通过网络进行传输。H.264是目前比较主流的压缩算法,像视频会议设备一般都采用这个编码格式。基础的H.264可以支持在1M带宽下传输720P30帧/秒的图像;H.264 HIGH PROFILE支持在512K带宽下传输720P30帧/秒的图像。 H.265是比较新的压缩算法,可以更一步提高压缩比,随着我们现在生活中出现的视频格式越来越大(比如现在基本都是1080P甚至4K的显示器

weixin_40673765的博客 8936

php双向循环链表,简单的双向循环链表实现的队列

#ifndef _LIST_H#define _LIST_Hstruct listrec;typedef struct listrec *list;list listinit( );void print( list L );void insert( list L, int abc );void deleteall( list L );#endifstruct listrec{int elem;l...

weixin_29711471的博客 147

ABAP传输自定义IDOC实例

首先确定出站方和入站方,本例中我使用150作为发送方将200作为接收方。 发送端系统配置 进入tcode-SALE,点击定义逻辑系统,这里我定义D01CLNT150为发送端, D01CLNT200为接收端 2,将逻辑系统分配给对应的client 3,进入tcode-WE31,创建IDOC开发段(segment)这里可以按照实际需求创建想要传输的结构,为求简单我创建了ZKNA1并选取了几个客户主数据的字段作为示例 4,进入tcode-WE30,创建Idoc Ty...

Nathan的博客 4076

卷积码Viterbi译码算法原理及C语言实现

具体而言,卷积码的编码过程是将输入数据和编码器中的状态进行异或操作,输出码字为各个状态对应的结果。Viterbi译码算法是一种最大似然译码算法,根据接收到的含有噪声的码字,寻找出最有可能的原始数据序列。(2) 递推计算:根据接收到的码字和当前状态,计算下一时刻各个状态的路径度量,并记录每个状态的前驱状态。以上代码实现了一个简单的卷积码Viterbi译码算法,通过接收到的码字进行译码,并输出解码结果。(1) 初始化:将所有状态的路径度量初始化为一个很大的值,选择路径度量最小的状态作为起始状态。

2301_79331421的博客 825

php双向链表+性能,PHP双向链表定义与用法示例

本文实例讲述了PHP双向链表定义与用法。分享给大家供大家参考,具体如下:由于需要对一组数据多次进行移动操作,所以写个双向链表。但对php实在不熟悉,虽然测试各个方法没啥问题,就是不知道php语言深层的这些指针和unset有什么注意的地方,贴出来让大家教育吧。效率没测试....求谅解~/*** **双向链表* @author zhiyuan12@*//*** 链表元素结点类*/class Node_...

weixin_35308269的博客 85

【目标检测】IoU(交并比)详解及代码实现

1. IOU概述        IoU的全称为交并比(Intersection over Union),是目标检测中使用的一个概念,IoU计算的是“预测的边框”和“真实的边框”的交叠率-,即它们的交集和并集的比值。最理想情况是完全重叠,即比值为1。 2. IoU计算        IoU等于“预测的边框”和“真实的边框”之间交集和并集的比值。IoU计算如下图,B1为真实

Roaddd的博客 2万+

PHP实现双向链表、栈

php //双向链表 class Hero { public $pre=null;//前指针 public $no;//排名 public $name;//名字 public $next=null;//后指针

lchmyhua88的博客 331

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

java+单向链表+双向链表_java+单向链表+双向链表

java+单向链表+双向链表[2021-02-05 17:16:37]简介:php如何实现链表?2020-07-10php实现链表的方法:首先定义一个节点类,代码为【function __construct($val=null)】;然后实现链表的实现类,代码为【function_construct $this->dummyhead = new Nod】。php实现C语言合并两个有序链表的...

weixin_31125161的博客 323

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

PHP内核之HashTable

文章目录哈希表定义HashTable性能理解PHP的哈希表实现1. HashTable在PHP内核的实现HashTable结构Bucket结构1.1 在PHP中初始化一个空数组时,对应内核中是如何创建HashTable的1.2 内核对PHP添加数字索引的处理方式1.3 内核对PHP中字符串索引的处理方式2. 内核中如何实现均匀分布和解决hash碰撞问题的2.1 均匀分布2.2 Hash碰撞 哈希表定义 哈希表(或散列表),是将键名key按指定的散列函数HASH经过HASH(key)计算后映射到表中一个记录

eight_eyes的博客 274

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

php双向链表,PHP实现双向链表、栈

这次再来分享一下实现双向链表和栈的实现。代码虽然是以前写的了,但是发现PHP写的这些代码很容易看懂!双向链表classHero{public $pre=null;//前指针public $no;//排名public $name;//名字public $next=null;//后指针/***构造函数,申明链表头*/public function __construct($no=‘‘,$name=‘‘...

weixin_29587015的博客 159

php 源码 双向链表,PHP实现双向链表_php

看了很久数据结构但是没有怎么用过,在网上看到了关于php的数据结构,学习了一下,与大家一起分享一下。上一次分享了链表,这次来补充说一下双向链表。简短不割复制代码class Hero{public $pre=null;public $no;public $name;public $next=null;public function __construct($no='',$name=''){$this...

weixin_29083649的博客 155

PHP实现双向链表的增删改查

PHP实现双向链表的增删改查 双向链表对比单项链表,有三部分组成: 指针 next,指向当前节点的下一个节点 指针 prev,指向当前节点的下一个节点 数据存储区 data, 当前节点的数据存储区 有两个指针,代表它更加复杂,同时也代表它比单项链表,既可以从头遍历,也可以从尾部遍历,更加灵活 示意图如下: 初始化一个节点类 主要数据 双向指针,以及节点数据 实例如下:...

LiYi 266

php 双向链表,Go实现双向链表

本文介绍什么是链表,常见的链表有哪些,然后介绍链表这种数据结构会在哪些地方可以用到,以及 Redis 队列是底层的实现,通过一个小实例来演示 Redis 队列有哪些功能,最后通过 Go 实现一个双向链表。目录1、链表1.1 说明1.2 单向链表1.3 循环链表1.4 双向链表2、redis队列2.1 说明2.2 应用场景2.3 演示3、Go双向链表3.1 说明3.2 实现4、总结5、参考文献1、链...

weixin_29185199的博客 208

php双向链表,PHP双向链表使用详解

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

weixin_35214204的博客 201

php双向链表+性能,PHP数据结构与算法:双向链表

一、概念1.定义双向链表也叫双面链表。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。 2.概述 3.指定位置插入节点 4.删除节点 二、PHP实现/*** 节点实现*/class Node{/*** 数据元素* @var*/public $item;/*** 前驱节点* @var*/public $prev;/...

weixin_34168167的博客 206

php数组实现:哈希 +双向链表

php数组实现原理 数组是PHPer最常用的数据类型,同时php容易上手也得益于其强大的数组,但是数组在php中是如何实现的呢? 首先,我们还是先了解下相关的数据结构,为下面的内容打好基础 哈希表   哈希表,顾名思义,即将不同的关键字映射到不同单元的一种数据结构。而将不同关键字映射到不同单元的方法就叫做哈希函数   理想情况下,经过哈希函数处理,关键字和单元是会进行一一对应的;但是如果...

技无涯的博客 490

php写双向链表,PHP小教程之实现双向链表

看了很久数据结构但是没有怎么用过,在网上看到了关于PHP的数据结构,学习了一下,与大家一起分享一下。上一次分享了《PHP小教程之实现链表》,这次来补充说一下双向链表。复制代码 代码如下:class Hero{public $pre=null;public $no;public $name;public $next=null;public function __construct($no='',$n...

weixin_34790081的博客 160

php实现一个双向链表,PHP双向链表定义与用法示例

本文实例讲述了PHP双向链表定义与用法。分享给大家供大家参考,具体如下:由于需要对一组数据多次进行移动操作,所以写个双向链表。但对php实在不熟悉,虽然测试各个方法没啥问题,就是不知道php语言深层的这些指针和unset有什么注意的地方,贴出来让大家教育吧。效率没测试....求谅解~/*****双向链表*@authorzhiyuan12@*//***链表元素结点类*/classNode_Eleme...

weixin_30717229的博客 200

php双向链表+性能,PHP双向链表基础详解

本文主要和大家介绍PHP双向链表定义与用法,涉及php使用双向链表类封装双向链表定义、读取、删除、插入等相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。由于需要对一组数据多次进行移动操作,所以写个双向链表。但对php实在不熟悉,虽然测试各个方法没啥问题,就是不知道php语言深层的这些指针和unset有什么注意的地方,贴出来让大家教育吧。效率没测试....求谅解~/*** **双向链表* @a...

weixin_36307377的博客 124
上一篇: D3.js——理解 update, enter, exit 的使用
下一篇: PHP代码注释规范
山木枝
博客等级 码龄11年 8粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值