欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP实现双向链表的一例代码

程序员文章站 2022-04-06 14:47:41
...
  1. /**
  2. * **双向链表
  3. * @author zhiyuan12@
  4. * @modified 2012-10-25
  5. * @site: bbs.it-home.org
  6. */
  7. /**
  8. * 链表元素结点类
  9. */
  10. class Node_Element {
  11. public $pre = NULL; // 前驱
  12. public $next = NULL; // 后继
  13. public $key = NULL; // 元素键值
  14. public $data = NULL; // 结点值
  15. function __Construct($key, $data) {
  16. $this->key = $key;
  17. $this->data = $data;
  18. }
  19. }
  20. /**
  21. * 双向链表类
  22. */
  23. class DoubleLinkedList {
  24. private $head; // 头指针
  25. private $tail; // 尾指针
  26. private $current; // 当前指针
  27. private $len; // 链表长度
  28. function __Construct() {
  29. $this->head = self::_getNode ( null, null );
  30. $this->curelement = $this->head;
  31. $this->tail = $this->head;
  32. $len = 0;
  33. }
  34. /**
  35. * @ desc: 读取链表全部结点
  36. */
  37. public function readAll() {
  38. $tmp = $this->head;
  39. while ( $tmp->next !== null ) {
  40. $tmp = $tmp->next;
  41. var_dump ( $tmp->key, $tmp->data );
  42. }
  43. }
  44. public function move($pos1, $pos2) {
  45. $pos1Node = $this->findPosition ( $pos1 );
  46. $pos2Node = $this->findPosition ( $pos2 );
  47. if ($pos1Node !== null && $pos2Node !== null) {
  48. $tmpKey = $pos1Node->key;
  49. $tmpData = $pos1Node->data;
  50. $pos1Node->key = $pos2Node->key;
  51. $pos1Node->data = $pos2Node->data;
  52. $pos2Node->key = $tmpKey;
  53. $pos2Node->data = $tmpData;
  54. return true;
  55. }
  56. return false;
  57. }
  58. /**
  59. * @ desc: 在指定关键词删除结点
  60. *
  61. * @param : $key
  62. * 指定位置的链表元素key
  63. */
  64. public function delete($key) {
  65. $pos = $this->find ( $key );
  66. if ($pos !== null) {
  67. $tmp = $pos;
  68. $last = null;
  69. $first = true;
  70. while ( $tmp->next !== null && $tmp->next->key === $key ) {
  71. $tmp = $tmp->next;
  72. if (! $first) {
  73. $this->delNode ( $last );
  74. } else {
  75. $first = false;
  76. }
  77. $last = $tmp;
  78. }
  79. if ($tmp->next !== null) {
  80. $pos->pre->next = $tmp->next;
  81. $tmp->next->pre = $pos->pre;
  82. } else {
  83. $pos->pre->next = null;
  84. }
  85. $this->delNode ( $pos );
  86. $this->delNode ( $tmp );
  87. }
  88. }
  89. /**
  90. * @ desc: 在指定位置删除结点
  91. *
  92. * @param : $key
  93. * 指定位置的链表元素key
  94. */
  95. public function deletePosition($pos) {
  96. $tmp = $this->findPosition ( $pos );
  97. if ($tmp === null) {
  98. return true;
  99. }
  100. if ($tmp === $this->getTail ()) {
  101. $tmp->pre->next = null;
  102. $this->delNode ( $tmp );
  103. return true;
  104. }
  105. $tmp->pre->next = $tmp->next;
  106. $tmp->next->pre = $tmp->pre;
  107. $this->delNode ( $tmp );
  108. }
  109. /**
  110. * @ desc: 在指定键值之前插入结点
  111. *
  112. * @param : $key
  113. * //指定位置的链表元素key
  114. * @param : $data
  115. * //要插入的链表元素数据
  116. * @param : $flag
  117. * //是否顺序查找位置进行插入
  118. */
  119. public function insert($key, $data, $flag = true) {
  120. $newNode = self::_getNode ( $key, $data );
  121. $tmp = $this->find ( $key, $flag );
  122. if ($tmp !== null) {
  123. $newNode->pre = $tmp->pre;
  124. $newNode->next = $tmp;
  125. $tmp->pre = $newNode;
  126. $newNode->pre->next = $newNode;
  127. } else {
  128. $newNode->pre = $this->tail;
  129. $this->tail->next = $newNode;
  130. $this->tail = $newNode;
  131. }
  132. $this->len ++;
  133. }
  134. /**
  135. * @ desc: 在指定位置之前插入结点
  136. *
  137. * @param : $pos
  138. * 指定插入链表的位置
  139. * @param : $key
  140. * 指定位置的链表元素key
  141. * @param : $data
  142. * 要插入的链表元素数据
  143. */
  144. public function insertPosition($pos, $key, $data) {
  145. $newNode = self::_getNode ( $key, $data );
  146. $tmp = $this->findPosition ( $pos );
  147. if ($tmp !== null) {
  148. $newNode->pre = $tmp->pre;
  149. $newNode->next = $tmp;
  150. $tmp->pre = $newNode;
  151. $newNode->pre->next = $newNode;
  152. } else {
  153. $newNode->pre = $this->tail;
  154. $this->tail->next = $newNode;
  155. $this->tail = $newNode;
  156. }
  157. $this->len ++;
  158. return true;
  159. }
  160. /**
  161. * @ desc: 根据key值查询指定位置数据
  162. *
  163. * @param : $key
  164. * //指定位置的链表元素key
  165. * @param : $flag
  166. * //是否顺序查找
  167. */
  168. public function find($key, $flag = true) {
  169. if ($flag) {
  170. $tmp = $this->head;
  171. while ( $tmp->next !== null ) {
  172. $tmp = $tmp->next;
  173. if ($tmp->key === $key) {
  174. return $tmp;
  175. }
  176. }
  177. } else {
  178. $tmp = $this->getTail ();
  179. while ( $tmp->pre !== null ) {
  180. if ($tmp->key === $key) {
  181. return $tmp;
  182. }
  183. $tmp = $tmp->pre;
  184. }
  185. }
  186. return null;
  187. }
  188. /**
  189. * @ desc: 根据位置查询指定位置数据
  190. *
  191. * @param : $pos
  192. * //指定位置的链表元素key
  193. */
  194. public function findPosition($pos) {
  195. if ($pos $this->len)
  196. return null;
  197. if ($pos len / 2 + 1)) {
  198. $tmp = $this->head;
  199. $count = 0;
  200. while ( $tmp->next !== null ) {
  201. $tmp = $tmp->next;
  202. $count ++;
  203. if ($count === $pos) {
  204. return $tmp;
  205. }
  206. }
  207. } else {
  208. $tmp = $this->tail;
  209. $pos = $this->len - $pos + 1;
  210. $count = 1;
  211. while ( $tmp->pre !== null ) {
  212. if ($count === $pos) {
  213. return $tmp;
  214. }
  215. $tmp = $tmp->pre;
  216. $count ++;
  217. }
  218. }
  219. return null;
  220. }
  221. /**
  222. * @ desc: 返回链表头节点
  223. */
  224. public function getHead() {
  225. return $this->head->next;
  226. }
  227. /**
  228. * @ desc: 返回链表尾节点
  229. */
  230. public function getTail() {
  231. return $this->tail;
  232. }
  233. /**
  234. * @ desc: 查询链表节点个数
  235. */
  236. public function getLength() {
  237. return $this->len;
  238. }
  239. private static function _getNode($key, $data) {
  240. $newNode = new Node_Element ( $key, $data );
  241. if ($newNode === null) {
  242. echo "new node fail!";
  243. }
  244. return $newNode;
  245. }
  246. private function delNode($node) {
  247. unset ( $node );
  248. $this->len --;
  249. }
  250. }
  251. // $myList = new DoubleLinkedList ();
  252. // $myList->insert ( 1, "test1" );
  253. // $myList->insert ( 2, "test2" );
  254. // $myList->insert ( "2b", "test2-b" );
  255. // $myList->insert ( 2, "test2-c" );
  256. // $myList->insert ( 3, "test3" );
  257. // $myList->insertPosition ( 5, "t", "testt" );
  258. // $myList->readAll ();
  259. // echo "+++";
  260. // $myList->deletePosition(0);
  261. // $myList->readAll ();
  262. // echo "..." . $myList->getLength ();
  263. // var_dump ( $myList->findPosition ( 3 )->data );
  264. ?>
复制代码