PHP實現簡單雙向連結串列
阿新 • • 發佈:2018-11-25
用PHP實現雙向連結串列,在實現上,與C++的區別,主要在指標與this的使用上的不同。在資料結構方面雙向連結串列要考慮兩個方向四個指向,每次增減節點時注意每個指向都要照顧到。
實現檔案DoubleLinkList.php
<?php
/**
* **雙向連結串列
* @author [email protected]
*
*/
/**
* 連結串列元素結點類
*/
class Node{
public $prev = NULL; // 前驅
public $next = NULL; // 後繼
public $key = NULL; // 元素鍵值
public $data = NULL; // 結點值
function __Construct($key, $data) {
$this->key = $key;
$this->data = $data;
}
}
class DoubleLinkList{
private $head;
private $tail;
private $current;
private $size;
function __Construct(){
$this->head = $this ->tail = NULL;
$this->size = 0;
}
/**
* 在連結串列頭部加入節點
* @param $key 要插入元素的key
* @param $data 要插入連結串列元素的資料
*/
public function addFirst($key, $data){
$newNode = new Node($key, $data);
$newNode->next = $this->head;
$this->head-> prev->next = $newNode;
$this->head->prev = $newNode;
$this->head = $newNode;
$this->size++;
if($this->tail === NULL){
$this->tail = $this->head;
}
}
/**
* 在連結串列尾部加入節點
* @param $key 要插入元素的key
* @param $data 要插入連結串列元素的資料
*/
public function addLast($key, $data){
if($this->tail === NULL){
$this->addFirst($key, $data);
}else{
$newNode = new Node($key, $data);
$newNode->prev = $this->tail;
$this->tail->next->prev = $newNode;
$this->tail->next = $newNode;
$this->tail = $newNode;
}
$this->size++;
}
/**
* 刪除連結串列頭部節點
*/
public function removeFirst(){
if($this->size == 0){
throw new Exception("The list is empty");
} else {
$tmp = $this->head;
$this->head = $tmp->next;
$this->head->prev = $tmp->prev;
if($this->head === NULL) $this->tail = NULL;
unset($tmp);
$this->size--;
}
}
/**
* 刪除連結串列尾部節點
*/
public function removeLast(){
if($this->size == 0){
throw new Exception("The list is empty");
} else {
$tmp = $this->tail;
$this->tail = $tmp->prev;
$this->tail->next = $tmp->next;
if($this->tail === NULL) $this->head = NULL;
unset($tmp);
$this->size--;
}
}
/**
* 獲得頭部節點的資料
* @throws 連結串列為空
*/
public function getFirst(){
if($this->size == 0){
throw new Exception("The list is empty");
} else {
var_dump($this->head->key, $this->head->data);
}
}
/**
* 獲得尾部節點的資料
* @throws 連結串列為空
*/
public function getLast(){
if($this->size == 0){
throw new Exception("The list is empty");
} else {
var_dump($this->tail->key, $this->tail->data);
}
}
/**
* 在指定位置插入節點
* @param $pos 指定元素在列表的位置
* @param $key 要插入元素的key
* @param $data 要插入連結串列元素的資料
*/
public function add($pos, $key, $data){
if($pos == 0){
$this->addFirst($key, $data);
}else if($pos >= $this->size){
$this->addLast($key, $data);
}else{
$this->current = $this->head;
for($i = 1; $i < $pos; $i++){
$this->current = $this->current->next;
}
$tmp = $this->current->next;
$newNode = new Node($key, $data);
$newNode->next = $tmp;
$newNode->prev = $this->current;
$this->current->next = $newNode;
$tmp->prev = $newNode;
$this->size++;
}
}
/**
* 在指定位置刪除節點
* @param $pos 指定元素在列表的位置
* @param $key 要插入元素的key
* @param $data 要插入連結串列元素的資料
*/
public function remove($pos){
if($pos == 0){
$this->removeFirst();
}else if($pos >= $this->size){
$this->removeLast();
}else{
$this->current = $this->head;
for($i = 1; $i < $pos; $i++){
$this->current = $this->current->next;
}
$tmp = $this->current->next;
$this->current->next = $tmp->next;
$tmp->next->prev = $this->current;
$this->size--;
}
}
/**
* 獲得所有節點的資料
* @throws 連結串列為空
*/
public function getAll(){
if($this->size == 0){
throw Exception("The list is empty");
} else {
$tmp = $this->head;
while($tmp !== NULL){
var_dump($tmp->key, $tmp->data);
$tmp = $tmp->next;
}
}
}
/**
* 根據key獲得指定節點的資料
* @param $key 指定的key值
* @return $data 對應的資料
*/
public function findByKey($key){
$tmp = $this->head;
while ($tmp !== NULL) {
if ($tmp->key === $key) {
return $tmp->data;
}
$tmp = $tmp->next;
}
return null;
}
/**
* 根據pos獲得指定節點的資料
* @param $pos 指定的key值
* @return $tmp 對應的key和data資料
*/
public function findByPos($pos){
if ($pos <= 0 || $pos > $this->size)
return null;
if ($pos < ($this->size / 2 + 1)) {
$tmp = $this->head;
$count = 0;
while ( $tmp->next !== null ) {
$tmp = $tmp->next;
$count++;
if ($count === $pos) {
return $tmp;
}
}
} else {
$tmp = $this->tail;
$pos = $this->size - $pos + 1;
$count = 1;
while ( $tmp->prev !== null ) {
if ($count === $pos) {
return $tmp;
}
$tmp = $tmp->pre;
$count++;
}
}
return null;
}
/**
* 清空連結串列
*/
public function clear(){
while($this->head !== NULL){
$tmp = $this->head;
$this->head = $this->head->next;
unset($tmp);
}
}
}
測試檔案
<?php
include "./DoubleLinkList.php";
$list = new DoubleLinkList();
$list->addFirst(1, "orange");
$list->addLast(2, "apple");
$list->addLast(3, "banana");
$list->addFirst(4, "grape");
$list->getFirst();
$list->removeFirst();
$list->getLast();
echo "-----------------";
$list->getAll();
echo "-----------------";
$list->removeLast();
$list->getAll();
echo "-----------------";
$list->add(1, 4, "peal");
$list->getAll();
echo "-----------------";
$list->add(1, 5, "watermoon");
$list->addFirst(6, "strawberry");
$list->remove(3);
$list->getAll();
echo "-----------------";
var_dump($list->findByKey(2));
echo "-----------------";
$a = $list->findByPos(2);
var_dump($a->key, $a->data);
echo "-----------------";
$list->clear();
$list->getAll();