PHP数组实现单链表的具体代码分享

开发 后端
PHP数组实现单链表主要是依靠PHP的数组系统用来模拟单链表的数据结构,希望本文所描述的内容对新手们有些帮助。

我们今天为大家带来的时候如何运用PHP数组实现单链表的具体方法。对于初学者来说,数组的正确和灵活运用还是比较生疏的,希望通过本文的介绍能够增加我们的编码经验,提高我们的变成能力。

#t#PHP数组实现单链表结构

此类主要是依靠PHP强大的数组系统来模拟出单链表类型的数据结构。 本人完全凭借自己的 兴趣来编写此类,并未考虑其实用性,主要是给大家理解一些简单的数据结构知识,同时也训练 一下PHP中的数组运用能力。

单链表简介:

单链表是最简单的链表表示。用它来表示线性表时,每一个数据元素占用一个结点(node)。一个 结点一般由两个域组成,一个域存放数据元素data; 另一个域存放一个指向链表中下一个结点的指针link,它指出下一个结点 的开始存储地址。而***一个结点的指针为空。单链表中数据元素之间的逻 辑关系是由结点中的指针指示的,换句话说,指针为数据元素之间的逻辑关系的映象,则逻辑上相邻的两个元素其存储的物理位置不要求紧邻,因此, 这种存储结构为非顺序映像或链式映像。当然,在PHP没有指针这个概念,但是我们可以用关联数组来模拟。

PHP数组实现单链表的代码如下:

  1. <?php 
  2. class LinkList   
  3. {  
  4.    /**  
  5.     * 成员变量  
  6.     * @var array    $linkList       链表数组  
  7.     * @var number   $listHeader     表头索引  
  8.     * @var number   $listLength     链表长度  
  9.     * @var number   $existedCounts  记录链表中出现过的元素的个数,和$listLength不同的是, 删除一  
  10.     *                               个元素之后,该值不需要减1,这个也可以用来为新元素分配索引。                            
  11.     */  
  12.    protected  $linkList  =array();  
  13.    protected  $listLength=0;  
  14.    protected  $listHeader=null;  
  15.    protected  $existedCounts=0;  
  16.    /**  
  17.     * 构造函数  
  18.     *   构造函数可以带一个数组参数,如果有参数,则调用成员方法  
  19.     * createList将数组转换成链表,并算出链表长度.如果没有参  
  20.     * 数,则生成一空链表.空链表可以通过调用成员方法createList  
  21.     * 生成链表.  
  22.     * @access public  
  23.     * @param  array $arr 需要被转化为链表的数组  
  24.     */  
  25.    public function __construct($arr='')  
  26.    {  
  27.      $arr!=null&&$this->createList($arr);  
  28.    }  
  29.    /**  
  30.     * 生成链表的函数  
  31.     *   将数组转变成链表,同时计算出链表长度。分别赋值给成员标量  
  32.     * $linkList和$listLength.  
  33.     * @access public  
  34.     * @param  array $arr 需要被转化为链表的数组  
  35.     * @return boolean  true表示转换成功,false表示失败    
  36.     */  
  37.   public function createList($arr)  
  38.   {   
  39.    if (!is_array($arr))   
  40.     return false;  
  41.    $length=count($arr);  
  42.    for($i=0;$i<$length;$i++)  
  43.    {     
  44.        if($i==$length-1)  
  45.        {  
  46.         //每个链表结点包括var和next两个索引,var表示结点值,next为下一个结点的索引  
  47.         //***一个结点的next为null  
  48.         $list[$i]['var']  =$arr[$i];  
  49.         $list[$i]['next'] =null;  
  50.        }  
  51.        else   
  52.        {  
  53.         $list[$i]['var']  =$arr[$i];  
  54.         $list[$i]['next'] =$i+1;  
  55.        }  
  56.    }  
  57.    $this->linkList      =$list;  
  58.    $this->listLength    =$length;  
  59.    $this->existedCounts =$length;  
  60.    $this->listHeader=0;  
  61.    return true;  
  62.   }  
  63.   /**  
  64.    * 将链表还原成一维数组  
  65.    * @access public  
  66.    * @return array    $arr  生成的一维数组  
  67.    */  
  68.   public function returnToArray()  
  69.   {   
  70.    $arr=array();  
  71.    $tmp=$this->linkList[$this->listHeader];  
  72.     for($i=0;$i<$this->listLength;$i++)  
  73.    {  
  74.      $arr[]=$tmp['var'];  
  75.      if ($i!=$this->listLength-1)   
  76.      {  
  77.      $tmp=$this->linkList[$tmp['next']];  
  78.      }  
  79.    }  
  80.    return $arr;  
  81.   }  
  82. public function getLength()  
  83.   {  
  84.           return $this->listLength;  
  85.   }  
  86.   /**  
  87.    * 计算一共删除过多少个元素  
  88.    * @access public   
  89.    * @return number $count 到目前为止删除过的元素个数  
  90.    */  
  91.   public function getDeletedNums()  
  92.   {  
  93.           $count=$this->existedCounts-$this->listLength;  
  94.           return $count;  
  95.   }  
  96.   /**  
  97.    * 通过元素索引返回元素序号  
  98.    * @access protected  
  99.    * @param  $index     元素的索引号  
  100.    * @return $num       元素在链表中的序号  
  101.    */  
  102.   public function getElemLocation($index)  
  103.   {  
  104.   if (!array_key_exists($index,$this->linkList))   
  105.    return false;  
  106.     $arrIndex=$this->listHeader;  
  107.     for($num=1;$tmp=$this->linkList[$arrIndex];$num++)  
  108.     {  
  109.             if ($index==$arrIndex)   
  110.             break;  
  111.             else   
  112.             {  
  113.                     $arrIndex=$tmp['next'];  
  114.             }  
  115.     }  
  116.     return $num;  
  117.   }  
  118.   /**  
  119.    * 获取第$i个元素的引用  
  120.    *   这个保护方法不能被外界直接访问,许多服务方法以来与次方法。  
  121.    * 它用来返回链表中第$i个元素的引用,是一个数组  
  122.    * @access protected  
  123.    * @param  number $i 元素的序号  
  124.    * @return reference 元素的引用  
  125.    */  
  126.   protected function &getElemRef($i)  
  127.   {  
  128.           //判断$i的类型以及是否越界  
  129.           $result=false;  
  130.           if (!is_numeric($i)||(int)$i<=0||(int)$i>$this->listLength)   
  131.           return $result;  
  132.    //由于单链表中的任何两个元素的存储位置之间没有固定关系,要取得第i个元素必须从  
  133.    //表头开始查找,因此单链表是非随机存储的存储结构。  
  134.    $j=0;  
  135.    $value=&$this->linkList[$this->listHeader];  
  136.    while ($j<$i-1)  
  137.    {  
  138.            $value=&$this->linkList[$value['next']];  
  139.            $j++;  
  140.    }  
  141.    return $value;  
  142.   }  
  143.   /**  
  144.    * 返回第i个元素的值  
  145.    * @access public  
  146.    * @param  number $i     需要返回的元素的序号,从1开始  
  147.    * @return mixed  第i个元素的值  
  148.    */  
  149.   public function getElemvar($i)  
  150.   {  
  151.     $var=$this->getElemRef($i);  
  152.     if ($var!=false)   
  153.     {  
  154.             return $var['var'];  
  155.     }  
  156.     else return false;  
  157.   }  
  158.   /**  
  159.    *   在第i个元素之后插入一个值为var的新元素  
  160.    *   i的取值应该为[1,$this->listLength],如果i=0,表示在表的最前段插入,  
  161.    * 如果i=$this->listLength,表示在表的末尾插入,插入的方法为,将第$i-1个元素  
  162.    * 的next指向第$i个元素,然后将第$i个元素的next指向第$i+1个元素,这样就实现了插入  
  163.    * @access public  
  164.    * @param  number $i   在位置i插入新元素  
  165.    * @param  mixed  $var 要插入的元素的值   
  166.    * @return boolean  成功则返回true,否则返回false  
  167.    */  
  168.   public function insertIntoList($i,$var)  
  169.   {  
  170.           if (!is_numeric($i)||(int)$i<0||(int)$i>$this->listLength)   
  171.           return false;  
  172.           if ($i==0)   
  173.           {  
  174.           //如果$i-0,则在表最前面添加元素,新元素索引为$listLength,这样是确保不会  
  175.           //覆盖原来的元素,另外这种情况需要重新设置$listHeader  
  176.               $this->linkList[$this->existedCounts]['var'] =$var;  
  177.               $this->linkList[$this->existedCounts]['next']=$this->listHeader;  
  178.               $this->listHeader=$this->existedCounts;  
  179.               $this->listLength++;  
  180.               $this->existedCounts++;  
  181.               return true;          
  182.           }  
  183.    $value=&$this->getElemRef($i);  
  184.    $this->linkList[$this->existedCounts]['var'] =$var;  
  185.    $this->linkList[$this->existedCounts]['next']=($i==$this->listLength?null:$value['next']);  
  186.    $value['next']=$this->existedCounts;  
  187.    $this->listLength++;  
  188.    $this->existedCounts++;  
  189.    return true;  
  190.   }  
  191.   /**  
  192.    * 删除第$i个元素  
  193.    *   删除第$i个元素,该元素为取值应该为[1,$this->listLength],需要注意,删除元素之后,  
  194.    * $this->listLength减1,而$this->existedCounts不变。删除的方法为将第$i-1个元素的  
  195.    * next指向第$i+1个元素,那么第$i个元素就从链表中删除了。  
  196.    * @access public  
  197.    * @param  number $i 将要被删除的元素的序号  
  198.    * @return boolean    成功则返回true,否则返回false  
  199.    */  
  200.   public function delFromList($i)  
  201.   {  
  202.           if (!is_numeric($i)||(int)$i<=0||(int)$i>$this->listLength)   
  203.           return false;  
  204.     if ($i==1)   
  205.     {  
  206.     //若删除的结点为头结点,则需要从新设置链表头  
  207.       $tmp=$this->linkList[$this->listHeader];  
  208.       unset($this->linkList[$this->listHeader]);  
  209.       $this->listHeader=$tmp['next'];  
  210.       $this->listLength--;  
  211.       return true;  
  212.     }  
  213.     else   
  214.     {  
  215.      $value    =&$this->getElemRef($i);  
  216.      $prevValue=&$this->getElemRef($i-1);  
  217.      unset($this->linkList[$prevValue['next']]);  
  218.      $prevValue['next']=$value['next'];  
  219.      $this->listLength--;  
  220.      return true;  
  221.     }  
  222.   }  
  223. /**  
  224.   * 对链表的元素排序  
  225.   *  谨慎使用此函数,排序后链表将被从新初始化,原有的成员变量将会被覆盖  
  226.   * @accse public  
  227.   * @param  boolean  $sortType='true' 排序方式,true表示升序,false表示降序,默认true     
  228.   */  
  229. public function listSort($sortType='true')  
  230. {  
  231.    //从新修改关联关系可能会更复杂,所以我选择先还原成一维数组,然后对数组排序,然后再生成链表  
  232.    $arr=$this->returnToArray();  
  233.    $sortType?sort($arr):rsort($arr);  
  234.    $this->createList($arr);  
  235. }  
  236. }  
  237. ?> 

上面这段代码就是PHP数组实现单链表的源码编写,希望对大家有所帮助。

责任编辑:曹凯 来源: phpchina.com
相关推荐

2009-11-25 15:50:53

PHP删除数组空白元素

2009-11-24 18:37:55

PHP数组转换

2009-11-24 13:26:17

2009-11-24 14:52:45

PHP动态多文件上传

2009-11-16 16:17:45

PHP数组排序

2009-11-25 17:28:26

PHP对话

2009-12-04 14:41:11

PHP数组变成JSON

2009-12-01 10:50:45

PHP函数requir

2022-03-10 17:02:51

Rust单链表数据结构

2009-11-25 11:42:34

PHP判断数组为空

2009-11-26 11:05:44

PHP计算页面执行时间

2009-12-03 17:57:35

PHP重定向代码

2009-12-02 17:22:22

PHP抓取图片

2009-11-25 11:33:26

PHP验证表单

2009-11-23 18:39:17

PHP重定向

2020-02-07 11:07:53

数组链表单链表

2009-12-01 14:26:19

PHP函数ob_sta

2009-11-30 18:21:21

PHP删除数组元素

2009-11-24 19:25:32

PHP关联数组

2009-11-24 20:09:35

PHP函数header
点赞
收藏

51CTO技术栈公众号