当前位置:Gxlcms > PHP教程 > PHP数组实现单链表的具体代码分享_PHP教程

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

时间:2021-07-01 10:21:17 帮助过:24人阅读

我们今天为大家带来的时候如何运用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数组实现单链表的源码编写,希望对大家有所帮助。


www.bkjia.comtruehttp://www.bkjia.com/PHPjc/446361.htmlTechArticle我们今天为大家带来的时候如何运用 PHP数组实现单链表结构 此类主要是依靠PHP强大的数组系统来模拟出单链表类型的数据结构。 本人完全...

人气教程排行