数据结构与算法之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三种语言的实现. ...
随机推荐
- Android Studio开发第一篇QuickStart
为什么把as的环境开发放在gradle里呢,因为eclipse里装gradle插件还是不够方便,as直接集成了,然后正好as也是大势所趋,学习一下正好. 看到右边Quick Start快速启动栏下面 ...
- 排序算法--冒泡排序(Bubble Sort)_C#程序实现
排序算法--冒泡排序(Bubble Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困 ...
- Java NIO学习笔记---Channel
Java NIO 的核心组成部分: 1.Channels 2.Buffers 3.Selectors 我们首先来学习Channels(java.nio.channels): 通道 1)通道基础 通道( ...
- Django详解之models操作
D jango 模型是与数据库相关的,与数据库相关的代码一般写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在settings.p ...
- day_6.22python多线程
僵尸进程:子进程结束,父类未结束 孤儿进程:父类进程over.,子进程未结束 0号进程负责运行,1号进程负责生成,所有孤儿进程的收容所(孤儿进程:父类进程over)1号进程,永不结束! Linux: ...
- Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式
PLY格式是比较流行的保存点云Point Cloud的格式,可以用MeshLab等软件打开,而VTK是医学图像处理中比较常用的格式,可以使用VTK库和ITK库进行更加复杂的运算处理.我们可以使用Par ...
- Flask----目录结构
以此结构为例,这个小项目是<Flask Web开发:基于python的web应用开发实战>第一部分结束后的代码框架 第一层 有app.tests.migrations三个文件夹和confi ...
- Jexus .Net at System.Net.Sockets.Socket.Connect (System.Net.IPAddress[] addresses, System.Int32 port)
环境:Jexus(独立版)+MVC(5.2.3) +Redis+EF(6.0) Application Exception System.Net.Sockets.SocketException Con ...
- Windows小技巧 -- 目录内打开CMD的快捷方式
工作中常常会有需要在某个文件夹内使用cmd的情况,例如运行某脚本,下面演示几种方法. 以进入以下目录操作为例: 方式一 : 常用的cd命令 cd命令是我们平常使用比较多的方式: 1. Win+R打开c ...
- PHP微信支付开发
此链接https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_2,是微信官方的示例,无效,报错. 1.申请微信支付的开通条件?什么样的账号可以 ...