数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)
链表是由一组节点组成的集合。每个节点都使用一个对象的引用指向它的后继。指向另一个节点的引用叫做链表。

插入:链表中插入一个节点的效率很高。向链表中插入一个节点,需要修改它前面的节点(前驱),使其指向新加入的节点,而新加入的节点则指向原来前驱指向的节点(见下图)。

由上图可知,B、C之间插入D,三者之间的关系为
current为插入节点的前驱节点
current->next = new // B节点指向新节点D
new->next = current->next // 新节点D指向B的后继节点C
删除:从链表中删除一个元素,将待删除元素的前驱节点指向待删除元素的后继节点,同时将待删除元素指向 null,元素就删除成功了(见下图)。

由上图可知,A、C之间删除B,三者之间的关系为
current为要删除节点的前驱节点
current->next = current->next->next // A节点指向C节点
具体代码如下:
<?php
// 节点类
class Node {
public $data; // 节点数据
public $next; // 下一节点 public function __construct($data) {
$this->data = $data;
$this->next = NULL;
}
}
// 单链表类
class SingleLinkedList {
private $header; // 头节点 function __construct($data) {
$this->header = new Node($data);
}
// 查找节点
public function find($item) {
$current = $this->header;
while ($current->data != $item) {
$current = $current->next;
}
return $current;
}
// (在节点后)插入新节点
public function insert($item, $new) {
$newNode = new Node($new);
$current = $this->find($item);
$newNode->next = $current->next;
$current->next = $newNode;
return true;
} // 更新节点
public function update($old, $new) {
$current = $this->header;
if ($current->next == null) {
echo "链表为空!";
return;
}
while ($current->next != null) {
if ($current->data == $old) {
break;
}
$current = $current->next;
}
return $current->data = $new;
} // 查找待删除节点的前一个节点
public function findPrevious($item) {
$current = $this->header;
while ($current->next != null && $current->next->data != $item) {
$current = $current->next;
}
return $current;
} // 从链表中删除一个节点
public function delete($item) {
$previous = $this->findPrevious($item);
if ($previous->next != null) {
$previous->next = $previous->next->next;
}
} // findPrevious和delete的整合
public function remove($item) {
$current = $this->header;
while ($current->next != null && $current->next->data != $item) {
$current = $current->next;
}
if ($current->next != null) {
$current->next = $current->next->next;
}
} // 清空链表
public function clear() {
$this->header = null;
} // 显示链表中的元素
public function display() {
$current = $this->header;
if ($current->next == null) {
echo "链表为空!";
return;
}
while ($current->next != null) {
echo $current->next->data . "  ";
$current = $current->next;
}
}
} $linkedList = new SingleLinkedList('header');
$linkedList->insert('header', 'China');
$linkedList->insert('China', 'USA');
$linkedList->insert('USA','England');
$linkedList->insert('England','Australia');
echo '链表为:';
$linkedList->display();
echo "</br>";
echo '-----删除节点USA-----';
echo "</br>";
$linkedList->delete('USA');
echo '链表为:';
$linkedList->display();
echo "</br>";
echo '-----更新节点England为Japan-----';
echo "</br>";
$linkedList->update('England', 'Japan');
echo '链表为:';
$linkedList->display();
//echo "</br>";
//echo "-----清空链表-----";
//echo "</br>";
//$linkedList->clear();
//$linkedList->display(); // 输出:
链表为:China USA England Australia
-----删除节点USA-----
链表为:China England Australia
-----更新节点England为Japan-----
链表为:China Japan Australia PHP实现单链表
二、双链表


current为插入节点的前驱节点
current->next = new // B的next属性指向新节点D
new->next = current->next // 新节点D的next属性指向B的后继节点C
current->next->previous = new // B的后继节点C的previous属性指向新节点D(原先是C的previous属性指向B)

current为要删除的节点
current->previous->next = current->next // B的前驱节点A的next属性指向B的后继节点C
current->next->previous = current->previous // B的后继节点C的previous属性指向B的前驱节点A
current->previous = null // B的previous属性指向null
current->next = null // B的next属性指向null
<?php
// 节点类
class Node {
public $data; // 节点数据
public $previous = NULL; // 前驱
public $next = NULL; // 后继 public function __construct($data) {
$this->data = $data;
$this->previous = NULL;
$this->next = NULL;
}
}
// 双链表类
class DoubleLinkedList {
private $header; // 头节点 function __construct($data) {
$this->header = new Node($data);
}
// 查找节点
public function find($item) {
$current = $this->header;
while ($current->data != $item) {
$current = $current->next;
}
return $current;
}
// 查找链表最后一个节点
public function findLast() {
$current = $this->header;
while ($current->next != null) {
$current = $current->next;
}
return $current;
}
//(在节点后)插入新节点
public function insert($item, $new) {
$newNode = new Node($new);
$current = $this->find($item);
$newNode->next = $current->next;
$newNode->previous = $current;
$current->next = $newNode;
return true;
}
// 从链表中删除一个节点
public function delete($item) {
$current = $this->find($item);
if ($current->next != null) {
$current->previous->next = $current->next;
$current->next->previous = $current->previous;
$current->next = null;
$current->previous = null;
return true;
}
}
// 显示链表中的元素
public function display() {
$current = $this->header;
if ($current->next == null) {
echo "链表为空!";
return;
}
while ($current->next != null) {
echo $current->next->data . "  ";
$current = $current->next;
}
}
// 反序显示双向链表中的元素
public function dispReverse() {
$current = $this->findLast();
while ($current->previous != null) {
echo $current->data . "  ";
$current = $current->previous;
}
}
} // 测试
$linkedList = new DoubleLinkedList('header');
$linkedList->insert('header', 'China');
$linkedList->insert('China', 'USA');
$linkedList->insert('USA','England');
$linkedList->insert('England','Australia');
echo '链表为:';
$linkedList->display();
echo "</br>";
echo '-----删除节点USA-----';
echo "</br>";
$linkedList->delete('USA');
echo '链表为:';
$linkedList->display(); // 输出:
链表为:China USA England Australia
-----删除节点USA-----
链表为:China England Australia PHP实现双链表
三、循环链表


current为插入节点的前驱节点
// 中间
current->next = new // B节点指向新节点D
new->next = current->next // 新节点D指向B的后继节点C
// 尾端
current->next = new // C节点指向新节点D
new->next = header // 新节点D指向头节点Header

current为要删除节点的前驱节点
// 中间
current->next = current->next->next // A节点指向C节点
// 尾端
current->next = header // B节点指向头节点Header
<?php
// 节点类
class Node {
public $data; // 节点数据
public $previous;
public $next; // 下一节点 public function __construct($data) {
$this->data = $data;
$this->next = NULL;
}
}
// 循环链表类
class CircularLinkedList {
private $header; // 头节点 function __construct($data) {
$this->header = new Node($data);
$this->header->next = $this->header;
}
// 查找节点
public function find($item) {
$current = $this->header;
while ($current->data != $item) {
$current = $current->next;
}
return $current;
}
// 插入新节点
public function insert($item, $new) {
$newNode = new Node($new);
$current = $this->find($item);
if ($current->next != $this->header) { // 链表中间
$current->next = $newNode;
$newNode->next = $current->next;
} else { // 链表尾端
$current->next = $newNode;
$newNode->next = $this->header;
}
return true;
}
// 删除节点
public function delete($item) {
$current = $this->header;
while ($current->next != null && $current->next->data != $item) {
$current = $current->next;
}
if ($current->next != $this->header) { // 链表中间
$current->next = $current->next->next;
} else { // 链表尾端
$current->next = $this->header;
}
}
// 显示链表中的元素
public function display() {
$current = $this->header;
while ($current->next != $this->header) {
echo $current->next->data . "  ";
$current = $current->next;
}
}
} // 测试
$linkedList = new CircularLinkedList('header');
$linkedList->insert('header', 'China');
$linkedList->insert('China', 'USA');
$linkedList->insert('USA', 'England');
$linkedList->insert('England', 'Australia');
echo '链表为:';
$linkedList->display();
echo "</br>";
echo '-----删除节点USA-----';
echo "</br>";
$linkedList->delete('USA');
echo '链表为:';
$linkedList->display();
// 输出:
链表为:China USA England Australia
-----删除节点USA-----
链表为:China England Australia PHP实现循环链表
数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)的更多相关文章
- 《Java数据结构与算法》笔记-CH5-链表-2单链表,增加根据关键字查找和删除
/** * Link节点 有数据项和next指向下一个Link引用 */ class Link { private int iData;// 数据 private double dData;// 数据 ...
- 《Java数据结构与算法》笔记-CH5-链表-1单链表
/** * Link节点 * 有数据项和next指向下一个Link引用 */ class Link { private int iData;//数据 private double dData;//数据 ...
- 数据结构和算法 – 4.字符串、 String 类和 StringBuilder 类
4.1.String类的应用 class String类应用 { static void Main(string[] args) { string astring = "Now is The ...
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- C# 数据结构 - 单链表 双链表 环形链表
链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- Linux内核中常用的数据结构和算法(转)
知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...
- 双链表算法原理【Java实现】(八)
前言 前面两节内容我们详细介绍了ArrayList,一是手写实现ArrayList数据结构,而是通过分析ArrayList源码看看内置实现,关于集合内容一如既往,本节课我们继续学习集合LinkedLi ...
- Python与数据结构[0] -> 链表/LinkedList[1] -> 双链表与循环双链表的 Python 实现
双链表 / Doubly Linked List 目录 双链表 循环双链表 1 双链表 双链表和单链表的不同之处在于,双链表需要多增加一个域(C语言),即在Python中需要多增加一个属性,用于存储指 ...
- 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现
概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...
随机推荐
- css - Grid网格布局
.wrapper{ display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 1 ...
- Tiobe最新编程语言排行
https://www.tiobe.com/tiobe-index/
- sencha touch/Ext Js 6 + 自定义扩展的用法
app.js中加入以下代码 //指定ux起调目录 Ext.Loader.setPath({ 'ux': 'app/ux' }); 在app目录中创建一个ux文件夹 假如我们使用这个扩展,扩展地址:ht ...
- C# Hashtable
哈希表(Hashtable) 在.NET Framework中,Hashtable 是 System.Collections 命名空间提供的一个容器,用于处理和表现类似 key-value 的键值对, ...
- 关于linux Centos 7一个网卡配置多个IP的方法
有时我们在工作中,会遇到一个网卡配置多个ip的情况,尤其是在linux服务器方面的应用教多 于是笔者将其配置过程整理如下,希望能帮到遇到同样问题的朋友,这里以vmware虚拟机下的Centos 7为例 ...
- 三剑客之awk
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...
- Inotify+rsync实现实时数据同步
使用rsync可以实现数据同步,但是即使使用crontab定时任务最小执行间隔为1分钟,在数据实时性要求比较高场合需使用inotify+rsync实现实时同步 下载inotify wget https ...
- Catch That Cow POJ - 3278 bfs map超时,短路判断顺序。
题意:可以把n边为n+1,n-1,n*2问从n到k的最少变化次数. 坑:标题写了.有点不会写bfs了... ac代码 #define _CRT_SECURE_NO_WARNINGS #include& ...
- Python:正则表达式
学习内容参考:Python正则表达式指南 匹配流程 语法表
- python--json串相关的loads dumps load dump
#1 json串长的像字典,但不是字典类型,是str类型 #例如:user_info为json串,dict为字典,如果txt文本中标识dict的内容 为json串user_info = '''{&qu ...