數組
是線性表數據結構中 順序存儲
的具體實現。用一組 連續
的內存空間,存儲 相同類型
的數據
鏈表
是線性表數據結構中 鏈式存儲的具體實現
。用 節點
的 指針
把各個節點串聯在一起
數組的基本操作
- 在指定位置插入元素
- 刪除指定元素
- 查找值等於給定值的元素
- 查找數組小標爲 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;
}
}