1 <?php
2
3 //结点类
4 class node {
5
6 public $data;
7 public $next;
8
9 function __construct($data) {
10 $this->data = $data;
11 $this->next = null;
12 }
13 }
14
15 //链表类,链表中所有结点位置标号从1起始
16 class linkList {
17
18 //头结点
19 private $header;
20
21 function __construct () {
22 $this->header = new node(null);
23 }
24
25 /**
26 * 判断链表是否为空
27 * @return bool
28 */
29 function isEmpty() {
30 return ($this->header->next == null);
31 }
32
33 /**
34 * 返回链表长度
35 * @return int
36 */
37 function getLength() {
38 $len = 0;
39 $link = $this->header;
40 while($link->next != null)
41 {
42 $len++;
43 $link = $link->next;
44 }
45 return $len;
46 }
47
48 /**
49 * 返回链表中值为$data的结点位置
50 * @return array(找到结点) false(未找到结点)
51 */
52 function find($data) {
53 $index = array();
54 $pos = 0;
55 $link = $this->header;
56 while($link != null)
57 {
58 if($link->data === $data) {
59 $index[] = $pos;
60 }
61 $pos++;
62 $link = $link->next;
63 }
64 if(count($index) == 0) $index = false;
65 return $index;
66 }
67
68 /**
69 * 在链表第$index个位置插入值为$data的结点
70 * @return bool
71 */
72 function insertAt($index, $data) {
73 if(($index > $this->getLength()) || ($index < 1))
74 return false;
75 $link = $this->header;
76 $pos = 0;
77 while($index != $pos) {
78 $prev = $link;
79 $pos++;
80 $link = $link->next;
81 }
82 $new = new node($data);
83 $prev->next = $new;
84 $new->next = $link;
85 return true;
86 }
87
88 /**
89 * 在链表末尾添加值为$data的结点
90 */
91 function append($data) {
92 $link = $this->header;
93 while($link->next != null)
94 {
95 $link = $link->next;
96 }
97 $link->next = new node($data);
98 }
99
100 /**
101 * 删除链表第$index个结点
102 * @return $deleted 删除结点的值
103 */
104 function deleteAt($index) {
105 if(($index > $this->getLength()) || ($index < 1))
106 return false;
107 $link = $this->header;
108 $pos = 0;
109 while($pos != $index) {
110 $prev = $link;
111 $pos++;
112 $link = $link->next;
113 }
114 $prev->next = $link->next;
115 $deleted = $link->data;
116 unset($link);
117 return $deleted;
118 }
119
120 /**
121 * 删除链表中所有值为$data的结点
122 */
123 function deleteIs($data) {
124 $link = $this->header;
125 while($link != null) {
126 if($link->data !== $data) {
127 $prev = $link;
128 $link = $link->next;
129 }
130 else {
131 $prev->next = $link->next;
132 unset($link);
133 $link = $prev->next;
134 }
135 }
136 }
137
138 /**
139 * 更新链表第$index个结点的值为$data
140 * @return $updated 更新前的值
141 */
142 function updateAt($index, $data) {
143 if(($index > $this->getLength()) || ($index < 1))
144 return false;
145 $link = $this->header;
146 $pos = 0;
147 while($pos != $index) {
148 $pos++;
149 $link = $link->next;
150 }
151 $updated = $link->data;
152 $link->data = $data;
153 return $updated;
154 }
155
156 /**
157 * 将链表中所有值为$old的结点值替换为$new
158 */
159 function replace($old, $new) {
160 $link = $this->header;
161 while($link != null) {
162 if($link->data === $old) {
163 $link->data = $new;
164 }
165 $link = $link->next;
166 }
167 }
168
169 /**
170 * 销毁链表
171 */
172 function destroy() {
173 $this->header->next = null;
174 }
175
176 /**
177 * 清空链表
178 * 保留链表长度,令链表中每个结点为值为NULL
179 */
180 function truncate() {
181 $link = $this->header;
182 while($link != null)
183 {
184 $link->data = null;
185 $link = $link->next;
186 }
187 }
188
189 /**
190 * 显示链表信息
191 */
192 function display() {
193 if($this->isEmpty()) {
194 echo "This is an empty linklist!\n";
195 return;
196 }
197
198 $len = $this->getLength();
199 if($len > 1)
200 $msg = "There are {$len} elements in this linklist:\n";
201 else
202 $msg = "There is only 1 element in this linklist:\n";
203 echo $msg;
204 $i = 1;
205 $link = $this->header;
206 while($link->next != null) {
207 $link = $link->next;
208 printf("Data %02d is %s\n",$i,$link->data);
209 $i++;
210 }
211 }
212
213 }
214
215 $testList = new linkList();
216 for($i=0;$i<20;$i++) {
217 $testList->append(chr(ord('A') + rand(0,25)));
218 }
219 $testList->display();
220 $element = 'B';
221 printf("Searching for Element %s ...\n",$element);
222 if(false !== ($pos = $testList->find($element))) {
223 for($i=0;$i<count($pos);$i++)
224 printf("Data %02d is %s\n",$pos[$i],$element);
225 }
226 else {
227 printf("Element %s is not found!\n",$element);
228 }
229 $testList->insertAt(2,'Z');
230 $testList->display();
231 $testList->updateAt(4,'G');
232 $testList->display();
233 $testList->deleteAt(6);
234 $testList->display();
235 $testList->replace('N','B');
236 $testList->display();
237 $testList->deleteIs('B');
238 $testList->display();
239 $testList->destroy();
240 $testList->append('X');
241 $testList->display();
242
243 ?>