PHP常用演算法和資料結構示例(必看篇)

gb4215287發表於2017-09-30

例項如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
</pre><pre name="code" class="php"><?php
/**
 * Created by PhpStorm.
 * User: qishou
 * Date: 15-8-2
 * Time: 上午9:12
 */
header("content-type:text/html;charset=utf-8");
$arr = array(3,5,8,4,9,6,1,7,2);
echo implode(" ",$arr)."<br/>";
//---------------------------------------
//       常用排序演算法
//---------------------------------------
//氣泡排序
function BubbleSort($arr){
  $length = count($arr);
  if($length<=1){
    return $arr;
  }
  for($i=0;$i<$length;$i++){
    for($j=$length-1;$j>$i;$j--){
      if($arr[$j]<$arr[$j-1]){
        $tmp = $arr[$j];
        $arr[$j] = $arr[$j-1];
        $arr[$j-1] = $tmp;
      }
    }
  }
  return $arr;
}
echo '氣泡排序:';
echo implode(' ',BubbleSort($arr))."<br/>";
 
//快速排序
function QSort($arr){
  $length = count($arr);
  if($length <=1){
    return $arr;
  }
  $pivot = $arr[0];//樞軸
  $left_arr = array();
  $right_arr = array();
  for($i=1;$i<$length;$i++){//注意$i從1開始0是樞軸
    if($arr[$i]<=$pivot){
      $left_arr[] = $arr[$i];
    }else{
      $right_arr[] = $arr[$i];
    }
  }
  $left_arr = QSort($left_arr);//遞迴排序左半部分
  $right_arr = QSort($right_arr);//遞迴排序右半部份
  return array_merge($left_arr,array($pivot),$right_arr);//合併左半部分、樞軸、右半部分
}
echo "快速排序:";
echo implode(' ',QSort($arr))."<br/>";
 
//選擇排序(不穩定)
function SelectSort($arr){
  $length = count($arr);
  if($length<=1){
    return $arr;
  }
  for($i=0;$i<$length;$i++){
    $min = $i;
    for($j=$i+1;$j<$length;$j++){
      if($arr[$j]<$arr[$min]){
        $min = $j;
      }
    }
    if($i != $min){
      $tmp = $arr[$i];
      $arr[$i] = $arr[$min];
      $arr[$min] = $tmp;
    }
  }
  return $arr;
}
echo "選擇排序:";
echo implode(' ',SelectSort($arr))."<br/>";
 
//插入排序
function InsertSort($arr){
  $length = count($arr);
  if($length <=1){
    return $arr;
  }
  for($i=1;$i<$length;$i++){
    $x = $arr[$i];
    $j = $i-1;
    while($x<$arr[$j] && $j>=0){
      $arr[$j+1] = $arr[$j];
      $j--;
    }
    $arr[$j+1] = $x;
  }
  return $arr;
}
echo '插入排序:';
echo implode(' ',InsertSort($arr))."<br/>";
//---------------------------------------
//       常用查詢演算法
//---------------------------------------
//二分查詢
function binary_search($arr,$low,$high,$key){
  while($low<=$high){
    $mid = intval(($low+$high)/2);
    if($key == $arr[$mid]){
      return $mid+1;
    }elseif($key<$arr[$mid]){
      $high = $mid-1;
    }elseif($key>$arr[$mid]){
      $low = $mid+1;
    }
  }
  return -1;
}
$key = 6;
echo "二分查詢{$key}的位置:";
echo binary_search(QSort($arr),0,8,$key);
 
//順序查詢
function SqSearch($arr,$key){
  $length = count($arr);
  for($i=0;$i<$length;$i++){
    if($key == $arr[$i]){
      return $i+1;
    }
  }
  return -1;
}
$key = 8;
echo "<br/>順序常規查詢{$key}的位置:";
echo SqSearch($arr,$key);
//---------------------------------------
//       常用資料結構
//---------------------------------------
//線性表的刪除(陣列實現)
function delete_array_element($arr,$pos){
  $length = count($arr);
  if($pos<1 || $pos>$length){
    return "刪除位置出錯!";
  }
  for($i=$pos-1;$i<$length-1;$i++){
    $arr[$i] = $arr[$i+1];
  }
  array_pop($arr);
  return $arr;
}
$pos = 3;
echo "<br/>除第{$pos}位置上的元素後:";
echo implode(' ',delete_array_element($arr,$pos))."<br/>";
 
/**
 * Class Node
 * PHP模擬連結串列的基本操作
 */
class Node{
  public $data = '';
  public $next = null;
}
//初始化
function init($linkList){
  $linkList->data = 0; //用來記錄連結串列長度
  $linkList->next = null;
}
//頭插法建立連結串列
function createHead(&$linkList,$length){
  for($i=0;$i<$length;$i++){
    $newNode = new Node();
    $newNode->data = $i;
    $newNode->next = $linkList->next;//因為PHP中物件本身就是引用所以不用再可用“&”
    $linkList->next = $newNode;
    $linkList->data++;
  }
}
//尾插法建立連結串列
function createTail(&$linkList,$length){
  $r = $linkList;
  for($i=0;$i<$length;$i++){
    $newNode = new Node();
    $newNode->data = $i;
    $newNode->next = $r->next;
    $r->next = $newNode;
    $r = $newNode;
    $linkList->data++;
  }
}
//在指定位置插入指定元素
function insert($linkList,$pos,$elem){
  if($pos<1 && $pos>$linkList->data+1){
    echo "插入位置錯誤!";
  }
  $p = $linkList;
  for($i=1;$i<$pos;$i++){
    $p = $p->next;
  }
  $newNode = new Node();
  $newNode->data = $elem;
  $newNode->next = $p->next;
  $p->next = $newNode;
}
//刪除指定位置的元素
function delete($linkList,$pos){
  if($pos<1 && $pos>$linkList->data+1){
    echo "位置不存在!";
  }
  $p = $linkList;
  for($i=1;$i<$pos;$i++){
    $p = $p->next;
  }
  $q = $p->next;
  $p->next = $q->next;
  unset($q);
  $linkList->data--;
}
//輸出連結串列資料
function show($linkList){
  $p = $linkList->next;
  while($p!=null){
    echo $p->data." ";
    $p = $p->next;
  }
  echo '<br/>';
}
 
$linkList = new Node();
init($linkList);//初始化
createTail($linkList,10);//尾插法建立連結串列
show($linkList);//列印出連結串列
insert($linkList,3,'a');//插入
show($linkList);
delete($linkList,3);//刪除
show($linkList);
 
/**
 * Class Stack
 * 用PHP模擬順序棧的基本操作
 */
class Stack{
  //用預設值直接初始化棧了,也可用構造方法初始化棧
  private $top = -1;
  private $maxSize = 5;
  private $stack = array();
 
  //入棧
  public function push($elem){
    if($this->top >= $this->maxSize-1){
      echo "棧已滿!<br/>";
      return;
    }
    $this->top++;
    $this->stack[$this->top] = $elem;
  }
  //出棧
  public function pop(){
    if($this->top == -1){
      echo "棧是空的!";
      return ;
    }
    $elem = $this->stack[$this->top];
    unset($this->stack[$this->top]);
    $this->top--;
    return $elem;
  }
  //列印棧
  public function show(){
    for($i=$this->top;$i>=0;$i--){
      echo $this->stack[$i]." ";
    }
    echo "<br/>";
  }
}
 
$stack = new Stack();
$stack->push(3);
$stack->push(5);
$stack->push(8);
$stack->push(7);
$stack->push(9);
$stack->push(2);
$stack->show();
$stack->pop();
$stack->pop();
$stack->pop();
$stack->show();
 
/**
 * Class Deque
 * 使用PHP實現雙向佇列
 */
class Deque{
  private $queue = array();
  public function addFirst($item){//頭入隊
    array_unshift($this->queue,$item);
  }
  public function addLast($item){//尾入隊
    array_push($this->queue,$item);
  }
  public function removeFirst(){//頭出隊
    array_shift($this->queue);
  }
  public function removeLast(){//尾出隊
    array_pop($this->queue);
  }
  public function show(){//列印
    foreach($this->queue as $item){
      echo $item." ";
    }
    echo "<br/>";
  }
}
$deque = new Deque();
$deque->addFirst(2);
$deque->addLast(3);
$deque->addLast(4);
$deque->addFirst(5);
$deque->show();
 
//PHP解決約瑟夫環問題
//方法一
function joseph_ring($n,$m){
  $arr = range(1,$n);
  $i = 0;
  while(count($arr)>1){
    $i=$i+1;
    $head = array_shift($arr);
    if($i%$m != 0){ //如果不是則重新壓入陣列
      array_push($arr,$head);
    }
  }
  return $arr[0];
}
//方法二
function joseph_ring2($n,$m){
  $r = 0;
  for($i=2;$i<=$n;$i++){
    $r = ($r+$m)%$i;
  }
  return $r + 1;
}
echo "<br/>".joseph_ring(60,5)."<br/>";
echo "<br/>".joseph_ring2(60,5)."<br/>";

來源:http://www.jb51.net/article/108482.htm

相關文章