数组
是线性表数据结构中 顺序存储
的具体实现。用一组 连续
的内存空间,存储 相同类型
的数据
链表
是线性表数据结构中 链式存储的具体实现
。用 节点
的 指针
把各个节点串联在一起
数组的基本操作
- 在指定位置插入元素
- 删除指定元素
- 查找值等于给定值的元素
- 查找数组小标为 index 的元素
根据 线性表
顺序存储的数据结构特征,我们可以知道,数组的 插入、删除
时间复杂度为 O(n)
,因为涉及到数据的搬移操作;数组的 根据下标访问元素
的时间复杂度为 O(1)
,这是 连续的内存空间
带来的优势,根据 寻址公式
我们可以很容易的找到指定下标的内存地址
数组的代码实现 (PHP)
class MyArray
{
// 数组大小
private $size;
// 当前数组长度
private $len;
// 数组的数据
private $data;
/**
* 初始化数组
*/
public function __construct($size = 0)
{
if ($size <= 0) throw new Exception('Invalid Array size');
$this->size = $size;
$this->len = 0;
$this->data = array();
}
/**
* 判断数组是否已满
*/
private function full()
{
if ($this->size == $this->len) return true;
return false;
}
/**
* 索引是否超出范围
*/
private function outOfRange($index)
{
if ($index < 0 || $index >= $this->len) return true;
return false;
}
/**
* 根据索引访问数据元素
*/
public function find($index)
{
if (true === $this->outOfRange($index)) {
throw new Exception('Index out of range');
}
return $this->data[$index];
}
/**
* 在指定索引 index 处插入数据 data
*/
public function insert($index, $data)
{
if (true === $this->full()) {
throw new Exception('Array is full');
}
for ($i = $this->len - 1; $i >= $index; $i--) {
$this->data[$i] = $this->data[$i - 1];
}
$this->data[$index] = $data;
$this->len++;
return $index;
}
/**
* 删除指定索引的值
*/
public function delete($index)
{
if (true === $this->outOfRange($index)) {
throw new Exception('Index out of range');
}
$data = $this->data[$index];
for ($i = $index; $i < $this->len - 1; $i++) {
$this->data[$i] = $this->data[$i + 1];
}
// unset 掉移动元素后最后的重复元素
unset($this->data[$this->len - 1]);
$this->len--;
return $data;
}
}
链表的基本操作
- 初始化链表
- 插入一个节点
- 删除指定节点
- 查询值等于给定值的节点
链表的代码实现 (PHP)
class LinkedListNode
{
// 节点的数据
public $data;
// 节点的指针
public $next;
public function __construct($data = null)
{
$this->data = $data;
$this->next = null;
}
}
class LinkedList
{
/**
* 哨兵,头节点
* @var LinkedListNode
*/
public $head;
// 链表的长度
public $len;
/**
* 初始化链表
*/
public function __construct(LinkedListNode $head)
{
$this->head = $head;
$this->len = 0;
}
/**
* 插入节点,默认头插法 (头节点后插入)
*/
public function insert($value)
{
try {
$this->insertAfterNode($this->head, $value)
} catch (Exception $e) {
throw new Exception($e);
}
return true;
}
/**
* 查询值等于给定值的节点
*/
public function getNodeByValue($value)
{
$curNode = $this->head;
while(null !== $curNode) {
if ($value == $curNode->data) {
return $curNode;
}
$curNode = $curNode->next;
}
return null;
}
/**
* 查询链表的第 index 个节点
*/
public function getNodeByIndex($index)
{
if ($index <= 0 || $index > $this->len) {
throw new Exception('Index out of range');
}
$curNode = $this->head;
for ($i = 0; $i <= $index; $i++) {
$curNode = $curNode->next;
}
return $curNode;
}
public function delete(LinkedListNode $node)
{
if (null === $node) {
throw new Exception('Invalid node');
}
$preNode = $this->getPreNode($node);
$preNode->next = $node->next;
unset($node);
$this->len--;
return true;
}
private function getPreNode(LinkedListNode $node)
{
if (null === $node) {
throw new Exception('Invalid node');
}
$curNode = $this->head;
$preNode = $this->head;
while (null != $curNode && $curNode != $node) {
$preNode = $curNode;
$curNode = $curNode->next;
}
return $preNode;
}
/**
* 指定节点后插入元素
*/
private function insertAfterNode(LinkedListNode $node, $value)
{
if (null === $node) throw new Exception('Node is null');
$newNode = new LinkedListNode($value);
$newNode->next = $node->next;
$node->next = $newNode;
$this->len++;
return true;
}
}