PHP数据结构(二)——链式结构线性表

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

相关阅读:

PHP数据结构(一)——顺序结构线性表

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2717
来自专栏魂祭心

原 canvas绘制clock

4204
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2222
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

3919
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5656
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2606
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2665
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4878
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4074

扫码关注云+社区