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