(1)經常使用排序算法php
Class MySort { /* * 全部排序均按升序排序 * */ /** * 插入排序 * @param $arr * @param $st * @param $ed * 經過將元素插入到已排序的序列中不斷擴大已排序的序列 */ public function InsertSort(&$arr, $st, $ed) { for ($i = $st + 1; $i <= $ed; $i++) { $tmp = $arr[$i]; for ($j = $i - 1; $j >= $st; $j--) { if ($arr[$j] > $tmp) { // 若是元素比tmp大,就移動元素 $arr[$j + 1] = $arr[$j]; } else { break; } } $arr[$j + 1] = $tmp; } } /** * 冒泡排序 * @param $arr * @param $st * @param $ed * 經過不斷交換相鄰元素將更大的元素放在後邊,一趟交換以後就能把最大的元素放到最後邊,二趟排序能夠把次大的元素放在 * 倒數第二的位置,n趟排序就能夠把全部元素都放在正確的位置 */ public function BubbleSort(&$arr, $st, $ed) { for ($i = $ed - 1; $i >= $st; $i--) { $flag = false; for ($j = $st; $j <= $i; $j++) { if ($arr[$j] > $arr[$j + 1]) { $tmp = $arr[$j]; $arr[$j] = $arr[$j + 1]; $arr[$j + 1] = $tmp; $flag = true; } } if (!$flag) { // 優化:若是不發生交換,說明已排好序,退出便可 return; } } } /** * 選擇排序 * @param $arr * @param $st * @param $ed * 每次選擇當前未排序序列最小的元素放在合適的位置,已選擇的最小元素構成了已排序序列,不斷擴大已排序序列便可實現整體排序 */ public function SelectSort(&$arr, $st, $ed) { for ($i = $st; $i <= $ed; $i++) { $min = $i; for ($j = $i; $j <= $ed; $j++) { if ($arr[$min] > $arr[$j]) { $min = $j; } } if ($min != $i) { $tmp = $arr[$min]; $arr[$min] = $arr[$i]; $arr[$i] = $tmp; } } } /** * 歸併排序 * @param $arr * @param $st * @param $ed * 歸併排序的關鍵在於不斷合併兩個排好序的序列,能夠經過遞歸實現 */ public function MergeSort(&$arr, $st, $ed) { if ($st < $ed) { $mid = floor(($st + $ed) / 2); // php數值默認使用float型計算,與Java和C不一樣,因此此處須要向下取整 $this->MergeSort($arr, $st, $mid); $this->MergeSort($arr, $mid + 1, $ed); $this->merge($arr, $st, $mid, $ed); } } /** * 歸併數組arr a1-a2 b1-b2部分 * @param $arr * @param $a1 * @param $a2 * @param $b1 * @param $b2 */ private function merge(&$arr, $st, $mid, $ed) { $tmp_arr = array(); $a = $st; $b = $mid + 1; while ($a <= $mid && $b <= $ed) { if ($arr[$a] < $arr[$b]) { $tmp_arr[] = $arr[$a]; $a++; } else { $tmp_arr[] = $arr[$b]; $b++; } } while ($a <= $mid) { $tmp_arr[] = $arr[$a]; $a++; } while ($b <= $ed) { $tmp_arr[] = $arr[$b]; $b++; } for ($i = $st; $i <= $ed; $i++) { $arr[$i] = $tmp_arr[$i - $st]; } echo json_encode(func_get_args()) . "***********" . json_encode($tmp_arr) . "\n"; } /** * 快速排序 * @param $arr * @param $st * @param $ed */ public function QuickSort(&$arr, $st, $ed) { if ($st < $ed) { $mid = $this->partition($arr, $st, $ed); $this->QuickSort($arr, $st, $mid - 1); $this->QuickSort($arr, $mid + 1, $ed); } } /** * 對數組arr $sd-$ed部分使用軸元素進行劃分 * @param $arr * @param $st * @param $ed * @return mixed */ private function partition(&$arr, $st, $ed) { $pivot = $arr[$st]; while ($st < $ed) { while ($st < $ed && $arr[$ed] > $pivot) $ed--; $arr[$st] = $arr[$ed]; while ($st < $ed && $arr[$st] <= $pivot) $st++; $arr[$ed] = $arr[$st]; } $arr[$st] = $pivot; return $st; } } $sort_obj = new MySort(); $arr = [2,9,6,4,0,3,1]; $sort_obj->MergeSort($arr, 0, 6); var_dump($arr);
(2)二分查找node
Class MyFind { /** * 二分查找 * @param $arr * @param $key * PS: 必須保證輸入的數組arr是升序排列的! */ public function binarySearch($arr, $key) { $st = 0; $ed = count($arr) - 1; while ($st <= $ed) { $mid = floor(($st + $ed) / 2); if ($key == $arr[$mid]) { return $mid; } elseif ($key < $arr[$mid]) { $ed = $mid - 1; } else { $st = $mid + 1; } } return -1; } /** * 使用遞歸實現二分查找 * @param $arr * @param $key */ public function binarySearchWithRecursion($arr, $key) { return $this->recursion($arr, $key, 0, count($arr) - 1); } private function recursion($arr, $key, $st, $ed) { if ($st > $ed) { return -1; } $mid = floor(($st + $ed) / 2); if ($key == $arr[$mid]) { return $mid; } elseif ($key < $arr[$mid]) { return $this->recursion($arr, $key, $st, $mid - 1); } else { return $this->recursion($arr, $key, $mid + 1, $ed); } } /** * 二叉搜索樹查找 * @param $root * @param $key * 二叉樹結點定義: * class ListNode { * public $left; * public $right; * public $value; * } */ public function binaryTreeSearch($root, $key) { while ($root != null) { if ($key == $root->value) { return $root; } elseif ($key < $root->value) { $root = $root->left; } else { $root = $root->right; } } return null; } /** * 二分查找不小於$key的最小數(不少算法會用到,好比一致性哈希算法) * @param $arr * @param $key * 進行二分查找時,最後查找的位置老是最接近key的位置,若是key不存在,則最後查找的位置必定是小於key的最大數或者大於key的最小數 */ public function binarySearchMinSupper($arr, $key) { $st = 0; $ed = count($arr) - 1; while ($st <= $ed) { $mid = floor(($st + $ed) / 2); if ($key == $arr[$mid]) { return $arr[$mid]; } elseif ($key < $arr[$mid]) { $ed = $mid - 1; } else { $st = $mid + 1; } } return $key > $arr[$mid] ? $arr[$mid + 1] : $arr[$mid]; // 此處數組可能越界
} } $find_obj = new MyFind(); $arr = [0,1,2,3,4,6,9]; $a = $find_obj->binarySearchMinSupper($arr, 2.1); var_dump($a);
(3)棧與隊列(順序棧、鏈式棧、順序隊列、鏈式隊列)算法
abstract Class MyStack { protected $capacity = -1; public function __construct($capacity = null) { if (isset($capacity)) { $this->capacity = $capacity; } } abstract public function push($val); abstract public function top(); abstract public function pop(); abstract public function isEmpty(); abstract public function isFull(); } Class MyArrayStack extends MyStack { //順序棧 protected $arr = array(); public function push($val) { if ($this->isFull()) { return false; } $this->arr[] = $val; return true; } public function top() { return !$this->isEmpty() ? end($this->arr) : null; } public function pop() { return !$this->isEmpty() ? array_pop($this->arr) : null; } public function isEmpty() { return count($this->arr) == 0; } public function isFull() { if ($this->capacity == -1) { return false; } return count($this->arr) == $this->capacity; } } Class MyLinkedStackNode { public $val; public $next; } Class MyLinkedStack { //鏈式棧 protected $pointer = null; protected $count = 0; public function push($val) { if ($this->isFull()) { return false; } $node = new MyLinkedStackNode(); $node->val = $val; $node->next = $this->pointer; $this->pointer = $node; $this->count++; return true; } public function top() { return !$this->isEmpty() ? $this->pointer->val : null; } public function pop() { if ($this->isEmpty()) { return null; } $val = $this->pointer->val; $this->pointer = $this->pointer->next; $this->count--; return $val; } public function isEmpty() { return $this->count == 0; } public function isFull() { if ($this->capacity == -1) { return false; } return $this->count == $this->capacity; } } abstract Class MyQueue { protected $capacity = -1; public function __construct($capacity = null) { if (isset($capacity)) { $this->capacity = $capacity; } } abstract public function enqueue($val); abstract public function front(); abstract public function dequeue(); abstract public function isEmpty(); abstract public function isFull(); } Class MyArrayQueue extends MyQueue { protected $arr = array(); public function enqueue($val) { if ($this->isFull()) { return false; } $this->arr[] = $val; return true; } public function front() { return !$this->isEmpty() ? $this->arr[0] : null; } public function dequeue() { return !$this->isEmpty() ? array_shift($this->arr) : null; } public function isEmpty() { return count($this->arr) == 0; } public function isFull() { return count($this->arr) == $this->capacity; } } Class MyLinkedQueueNode { public $val; public $next; } Class MyLinkedQueue extends MyQueue { protected $head = null, $tail = null; protected $count = 0; public function enqueue($val) { if ($this->isFull()) { return false; } $node = new MyLinkedQueueNode(); $node->val = $val; if ($this->head == null) { //若是隊列爲空,效果等同於$this->isEmpty() $this->head = $this->tail = $node; } else { $this->tail->next = $node; $this->tail = $this->tail->next; } return true; } public function front() { return !$this->isEmpty() ? $this->head->val : null; } public function dequeue() { if ($this->isEmpty()) { return null; } $val = $this->head->val; if ($this->head == $this->tail) { //若是隻有一個元素 $this->head = $this->tail = null; } else { $this->head = $this->head->next; } $this->count--; return $val; } public function isEmpty() { return $this->count == 0; } public function isFull() { return $this->count == $this->capacity; } }