定义
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构
操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
链表的分类
单链表:它有一个表头,并且除了最后一个结点外,所有结点都有其后继节点
双向链表:它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。
循环链表:在双向链表的基础上做了优化,表中最后一个结点的指针域指向头结点,整个链表形成一个环。
静态链表:用数组来描述的链表,这种描述方法便于在没有指针类型的高级程序设计语言中使用链表结构
代码实现
注意边界条件
1:链表为空
2:超出链表范围
单链表的增删改查
class Node {
public $val;
public $next;
public function __construct($val=null, $next=null) {
$this->val = $val;
$this->next = $next;
}
}
include "node.php";
class LinkList {
public $head; //表头节点
public $size; //长度
public function __construct() {
$this->head = new Node();
$this->size = 0;
}
//头插法
public function addFirst($value) {
$this->add(0, $value);
}
//尾插法
public function addLast($value) {
$this->add($this->size, $value);
}
/**
* 通用插入方法 指定索引位置
* @param $index int
* @param $value mixed
* @throws Exception
*/
public function add($index, $value) {
if($index > $this->size) {
echo "超过链表范围"."\n";
return;
}
$prev = $this->head;
for($i = 0; $i < $index; $i++) {
$prev = $prev->next;
}
$prev->next = new Node($value, $prev->next);
$this->size++;
}
/**
* 判断是否存在某个元素
* @param $value mixed
* @return bool
*/
public function contain($value) {
$prev = $this->head;
if($prev == null) {
echo "链表为空"."\n";
return;
}
$contain = false;
while($prev->next != null) {
if($prev->next->val == $value) {
$contain = true;
break;
}
$prev = $prev->next;
}
return $contain;
}
/**
* 删除指定位置的值
* @param $index int
* @return
*/
public function delete($index) {
if($index > $this->size-1) {
echo "超出链表范围"."\n";
return;
}
$prev = $this->head;
for($i=0; $i <= $index; $i++) {
if($i == $index) {
$prev->next = $prev->next->next;
break;
}
$prev = $prev->next;
}
$this->size--;
}
/**
* 修改指定位置的值
* @param $index int
* @param $value mixed
* @return
*/
public function update($index, $value) {
$prev = $this->head;
if($index > $this->size-1) {
echo "超出链表范围";
return;
}
for($i = 0; $i <= $index; $i++) {
if($i == $index) {
break;
}
$prev = $prev->next;
}
$prev->next->val = $value;
}
/**
* 获取指定位置的值
* @param $index int
* @param return
*/
public function getValueByIndex($index) {
$prev = $this->head;
if($prev == null) {
echo "链表为空";
return;
}
if($index > $this->size-1){
echo "超出链表范围";
return;
}
$prev = $prev->next;
for($i = 0; $i <= $index; $i++) {
if($i == $index) {
return $prev->val;
}
$prev = $prev->next;
}
return "";
}
}
include "./singelLinkList.php";
$linkList = new LinkList();
$linkList->addFirst("aaa");
$linkList->addFirst(111);
$linkList->addLast("ccc");
var_dump($linkList->contain("aaa"))."\n";
var_dump($linkList->contain(13123))."\n";
$linkList->delete(10);
$linkList->delete(1);
$linkList->update(1,"test");
echo $linkList->getValueByIndex(1)."\n";
echo $linkList->getValueByIndex(2);
print_r($linkList);
结尾
本篇文章只是实现了单链表,感兴趣的话大家可以自己练习下双向链表,循环链表。