Maison  >  Article  >  développement back-end  >  PHP实现双向链表的一例代码

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

WBOY
WBOYoriginal
2016-07-25 08:57:401213parcourir
  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. ?>
复制代码


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn