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 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

《笨办法学Python》 第32课手记

《笨办法学Python》 第32课手记 本节课讲for循环和list,list里类似于c中的数组,但有区别很大。C语言中的数组是数据类型相同的值的集合,list...

1999
来自专栏用户2442861的专栏

C++ STL空间配置源码分析以及实现二

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

792
来自专栏Java学习网

Java面试中最常见的10个问题,Java底层知识,花点时间学习一下

1.什么是 Java 虚拟机?为什么 Java 被称作是“平台无关的编程语言”? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文...

2485
来自专栏GreenLeaves

JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍

1、原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct、Array、String等等)都在构造函数的原型上定义方法和属性。如...

20510
来自专栏风中追风

==和equals的区别

==比较的是内存地址,equals方法在object里源代码也是用==来比较,比较的也是内存地址;

3157
来自专栏IT可乐

Java中的增强 for 循环 foreach

  foreach 是 Java 中的一种语法糖,几乎每一种语言都有一些这样的语法糖来方便程序员进行开发,编译期间以特定的字节码或特定的方式来对这些语法进行处理...

1869
来自专栏Petrichor的专栏

python: 多属性排序

992
来自专栏GreenLeaves

JS框架设计之对象扩展一种子模块

对象扩展 说完了,对象的创建(框架的命名空间的创建)以及如何解决多库之间的命名空间冲突问题之后,接下来,就是要扩展我们的对象,来对框架进行扩展,我们需要一种新功...

2139
来自专栏人工智能LeadAI

Python中defaultdict用法

defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值

904
来自专栏康怀帅的专栏

PHP 面向对象

面向对象三大特性:封装、继承、多态。 官方文档:http://php.net/manual/zh/language.oop5.php 要创建一个类的实例,必须使...

3317

扫码关注云+社区