博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实战PHP数据结构基础之双链表
阅读量:6799 次
发布时间:2019-06-26

本文共 3155 字,大约阅读时间需要 10 分钟。

什么是双链表?

上一篇说到

单链表由一个一个的作为节点的对象构成的,每一个节点都有指向下一个节点的指针,最后一个节点的指针域指向空。每个节点可以存储任何数据类型。

而双链表每个节点有两个指针域,分别指向前驱和后继节点。单链表是单向的,而双链表是双向的。

常见操作

对双链表我们常见的操作有如下:

  • insert
  • insertBefore
  • insertAfter
  • insertAtFirst
  • insertAtLast
  • deleteFirst
  • deleteLast
  • delete
  • reverse
  • getNthNode
  • ...

PHP语言实现

首先我们根据定义实现一个双链表的ListNode类。

class ListNode{    public $data = null;    public $next = null;    public $prev = null;    public function __construct(string $data)    {        $this->data = $data;    }}

再来看链表类,首先需要3个私有属性,分别是头节点、尾巴节点和长度。

class DoubleLinkedList{    private $head = null;    private $last = null;    private $length = 0;}

接下来还是老规矩,直接看如何实现第一个即常用的插入,这是是一个平均时间复杂度为O(n)的操作。

/** * 插入一个节点 * @param string|null $data * @return bool * complexity O(n) */public function insert(string $data = null){    $newNode = new ListNode($data);    if ($this->head) {        $currentNode = $this->head;        while ($currentNode) {            if ($currentNode->next === null) {                $currentNode->next = $newNode;                $newNode->prev = $currentNode;                $this->last = $newNode;                $this->length++;                return true;            }            $currentNode = $currentNode->next;        }    } else {        $this->head = &$newNode;        $this->last = $newNode;        $this->length++;        return true;    }}

再来看如何删除节点。

/** * 删除一个节点 * @param string $data * @return bool|ListNode * complexity O(n) */public function delete(string $query = null){if ($this->head) {    $currentNode = $this->head;    $prevNode = null;    while ($currentNode) {        if ($currentNode->data === $query) {            if ($nextNode = $currentNode->next) {                if ($prevNode) {                    $prevNode->next = $nextNode;                    $nextNode->prev = $prevNode;                } else {                    $this->head = $nextNode;                    $nextNode->prev = null;                }                unset($currentNode);            } else {                if ($prevNode) {                    $this->last = $prevNode;                    $prevNode->next = null;                    unset($currentNode);                } else {                    $this->head = null;                    $this->last = null;                }            }            $this->length--;            return true;        }        $prevNode = $currentNode;        $currentNode = $currentNode->next;    }}    return false;}

反转双链表也不是很复杂。

public function reverse(){    if ($this->head !== null) {        if ($this->head->next !== null) {            $reversedList = null;            $currentNode = $this->head;            while ($currentNode !== null) {                $next = $currentNode->next;                $currentNode->next = $reversedList;                $currentNode->prev = $next;                $reversedList = $currentNode;                $currentNode = $next;            }            $this->last = $this->head;            $this->head = $reversedList;        }    }}

双链表其他操作的详细实现可以参考 。

双链表是链表这种链式存取数据结构中相对于单链表比较特殊的部分,同样属于链表结构的还有单链表,环形链表和多链表。

专题系列

PHP基础数据结构专题系列目录地址: 主要使用PHP语法总结基础的数据结构和算法。还有我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。

转载地址:http://ziywl.baihongyu.com/

你可能感兴趣的文章
[Oracle]PDB Clone 方法
查看>>
JavaScript词法作用域与调用对象
查看>>
当谈论设备指纹时,我们到底在说什么?(转)
查看>>
Python天天美味(10) - 除法小技巧
查看>>
webrtc进阶-信令篇-之三:信令、stun、turn、ice
查看>>
.NET调试实例-信息和安装说明 (原创翻译)
查看>>
ThinkPHP 数据库操作之数据表模型和基础模型 ( Model
查看>>
Listener and sqlnet trace
查看>>
Unity3D对安卓盒子的支持
查看>>
redis源码笔记 - redis-cli.c
查看>>
QTabWiget Change Color 改变颜色
查看>>
模板方法在Spring事务中的应用
查看>>
Ext.LoadMask遮罩的效果几种实现方式
查看>>
理解SQL SERVER中非聚集索引的覆盖,连接,交叉和过滤
查看>>
各个JAVA场景下的内存图
查看>>
用GMF生成简化的数据库设计器
查看>>
【干货】程序员常访问的国外技术交流网站汇总
查看>>
HDU 2503 a/b + c/d(最大公约数与最小公倍数,板子题)
查看>>
Java直接内存与非直接内存性能测试
查看>>
linux watchdog demo hacking
查看>>