PHP数据结构(二)——链式结构线性表
(原创内容,转载请注明来源,谢谢)
线性表分为顺序结构和链式结构,链式结构里每一个数据单元除了有数据之外,还有一个空间指向下一个数据的位置(双向链表里面还有一个指向前一个单元的位置)。
链式结构根据其方向性分为单向链表和双向链表,根据其循环性分为普通链表和循环链表。
单向链表:每个数据单元有数据和指向后继数据单元的位置。
双向链表:每个数据单元有数据和指向前驱以及后继单元的位置。
循环链表:链表的最后一个数据指向链表的第一个数据。
普通链表:链表的最后一个数据指向空(Null)。
另外,通常链表里面还有两个概念:
1:头指针,表示链表的开始,本身没有数据内容,指向链表第一个数据。
2:尾指针,表示链表的结束,本身没有数据内容,指向null(循环链表中指向头指针)。
优点:由于链表的每个单元之间的连接是根据指向的,因此对于链表的插入和删除操作较为方便,只需要修改链表中的指向即可。
缺点:查询、修改链表中的某个元素时,不好查找,需要遍历整个链表。对于单向链表,甚至链表前面的元素都无法快速查找,需要从头遍历。
用PHP实现双向循环链表的生成、增删改查。
结果如下:
源代码如下:
<?php
class chain{
//数值、前驱、后继
public $chaintable;
public $prev;
public $next;
//构造
public function__construct($chaintable=null){
$this->chaintable =$chaintable;
}
//生成链表
public function generate($arrChain){
$tail = new chain();
$this->prev = $tail;
$tail->next = $this;
$cur = $this;
foreach($arrChain as $item){
$tmp = newchain($item);
$cur->next =$tmp;
$tmp->prev =$cur;
$cur = $tmp;
}
$cur->next = $tail;
$tail->prev = $cur;
}
//展示链表
public function show(){
$tmp = $this;
while($tmp->next->chaintable!=null){
echo '<br/>'.$tmp->next->chaintable;
$tmp =$tmp->next;
}
}
//获取链表长度
public function length(){
$i = 0;
$tmp = $this;
while($tmp->next->chaintable!=null){
$i++;
$tmp = $tmp->next;
}
return $i;
}
//查找第i个元素
public function search($i){
$tmp = $this;
$chain_length =$tmp->length();
if($i<=0 ||$i>$chain_length){
echo '<br />元素超出链表长度';
}else{
$j = 0;
while($j<$i){
$j++;
$tmp =$tmp->next;
}
echo '<br />第'.$i.'个元素是:'.$tmp->chaintable;
}
}
//合并有序链表
public function merge($old_chain,$new_chain){
$old_length =$old_chain->length();
$new_length =$new_chain->length();
$old_chain =$old_chain->next;//跳过头部
$new_chain = $new_chain->next;
$i = 1;
$j = 1;
$k = 1;//循环次数
$final_chain = new chain();
$tmp = new chain();
while($i<=$old_length&& $j<=$new_length){
if($old_chain->chaintable<= $new_chain->chaintable){
$old_chain->prev= $final_chain;
$final_chain->next= $old_chain;
$final_chain= $old_chain;//***把final_chain的指针往后一步
$old_chain= $old_chain->next;
$i++;
}else{
$new_chain->prev= $final_chain;
$final_chain->next= $new_chain;
$final_chain= $new_chain;//***把final_chain的指针往后一步
$new_chain= $new_chain->next;
$j++;
}
$k++;
}
if($i <= $old_length){
$final_chain->next= $old_chain;
$old_chain->prev= $final_chain;
}else{
$final_chain->next= $new_chain;
$new_chain->prev= $final_chain;
}
echo '<br />合并成功';
return $final_chain;
}
//修改链表第i个元素
public function modify($i, $data){
$tmp = $this;
$chain_length =$tmp->length();
if($i<=0 ||$i>$chain_length){
echo '<br />元素超出链表长度';
}else{
$j = 0;
while($j<$i){
$j++;
$tmp =$tmp->next;
}
$tmp->chaintable= $data;
echo '<br />修改成功';
}
}
//删除链表第i个元素
public function delete($i){
$tmp = $this;
$chain_length =$tmp->length();
if($i<=0 ||$i>$chain_length){
echo '<br />元素超出链表长度';
}else{
$j = 0;
while($j<$i-1){//找到第i个元素的前一个元素
$j++;
$tmp =$tmp->next;
}
$tmp->next =$tmp->next->next;
$tmp->next->next->prev= $tmp;
echo '<br />删除成功';
}
}
}
$my_chain = newchain();
$my_chain->generate(array(1,3,7,9,12,15,16));
$my_chain->show();
$chain_length =$my_chain->length();
echo '<br/>链表长度:'.$chain_length;
$my_chain->search(2);
$new_chain = newchain();
$new_chain->generate(array(2,3,5,8,13,19,20));
$my_chain->merge($my_chain,$new_chain);
$my_chain->show();
$my_chain->modify(3,6);
$my_chain->show();
$my_chain->delete(5);
$my_chain->show();
?>
—— written by linhxx 2017.06.14
相关阅读: