常见的算法PHP 版,自整理

  1 <?php
  2 
  3     //二分查找
  4     public function bin_search($arr,$k,$low = 0,$high = 0){    
  5         if($high == 0){
  6             $high = count($arr) - 1;
  7         }
  8         $mid  = intval(($low + $high) / 2);
  9         //递归查找 
 10         if($low <= $high){
 11             if($k == $arr[$mid]){
 12                 return $mid;
 13             }
 14             else if($k > $arr[$mid]){
 15                 return bin_search($arr,$k,$mid,$high);
 16             }
 17             else if($k < $arr[$mid]){
 18                 return bin_search($arr,$k,$low,$mid);
 19             }
 20         }
 21         return -1;
 22     }
 23     //顺序查找
 24     public function seq_search($arr,$k){        
 25         foreach ($arr as $key => $value) {
 26             if($value == $k ){
 27                 return $key;
 28             }            
 29         }
 30         return -1;
 31     }
 32     //删除元素
 33     public function del_element($arr,$i){
 34         $len = count($arr);
 35         for($j = $i; $j < $len; $j++){
 36             $arr[$j] = $arr[$j+1];
 37         }
 38         //弹出最后一个元素
 39         array_pop($arr);
 40         return $arr;
 41     }
 42     //冒泡排序
 43     public function bubble_sort($arr = array()){
 44         $len = count($arr);
 45         if($len <= 1){
 46             return $arr;
 47         }
 48         foreach ($arr as $k => $v) {
 49             for($i = $k; $i < $len - 1; $i++){
 50                 if($arr[$i] > $arr[$i+1]){
 51                     $n         = $arr[$i];
 52                     $arr[$i]   = $arr[$i+1];
 53                     $arr[$i+1] = $n;
 54                 } 
 55             }
 56         }
 57         return $arr;
 58     }
 59 
 60     //快速排序
 61     public function quick_sort($arr = array()){
 62         $len = count($arr);
 63         if($len <= 1){
 64             return $arr;
 65         }
 66         $mid       = $arr[0];
 67         $left_arr  = array();
 68         $right_arr = array();
 69         //判断值大于标记位或小于标记位
 70         for($i = 1 ; $i < $len ; $i++){
 71             if($arr[$i] <= $mid ){
 72                 $left_arr[] = $arr[$i];
 73             }else{
 74                 $right_arr[] = $arr[$i];
 75             }
 76                         
 77         }
 78         //递归数组
 79         $left_arr  = quick_sort($left_arr);
 80         $right_arr = quick_sort($right_arr);
 81         return array_merge($left_arr,array($mid),$right_arr);
 82     }
 83 
 84     //插入排序
 85     public function insert_sort($arr){
 86         $len = count($arr);
 87         for($i = 1; $i < $len ; $i++){
 88             $n = $arr[$i];
 89             $j = $i-1;
 90             while($arr[$j] > $n){
 91                 $arr[$j+1] = $arr[$j];
 92                 $arr[$j]   = $n;
 93                 $j--;
 94             }
 95         }
 96         return $arr;
 97     }
 98     //选择排序
 99     public function select_sort($arr){
100         $len = count($arr);
101         for($i = 0; $i < $len; $i++){
102             //循环次数为标记位
103             $k = $i;
104             for($j = $i + 1; $j < $len; $i++){
105                 //若比标记位小则成为标记位,并交换值
106                 if($arr[$k] > $arr[$j])
107                     $k = $j;
108                 if($k != $i){
109                     $tmp = $arr[$i];
110                     $arr[$i] = $arr[$k];
111                     $arr[$k] = $tmp;                    
112                 }
113             }
114         }
115         return $arr;
116     }
117 
118     /**
119     php堆排序实现原理
120     php程序中关于堆的一些概念:
121     假设n为当前数组的key则
122     n的父节点为 n>>1 或者 n/2(整除);
123     n的左子节点l= n<<1 或 l=n*2,n的右子节点r=(n<<1)+1 或 r=l+1
124     */
125     // $arr=array(1,8,7,2,3,4,6,5,9);
126     // /*
127     // 数组$arr的原形态结构如下:
128     //              1
129     //            /    \
130     //          8      7
131     //        /   \      / \
132     //      2     3      4  6
133     //     / \
134     //    5  9
135     // */
136     // heap_sort($arr);
137     // print_r($arr);
138     // /*
139     // 排序后生成标准的小顶堆结构如下:
140     //              1
141     //            /   \
142     //          2      3
143     //        /   \    /  \
144     //      4    5      6   7
145     //     / \
146     //    8  9
147     // 既数组:array(1,2,3,4,5,6,7,8,9)
148     // */
149     // }
150     public function heap_sort($arr){
151         $last = count($arr);
152         //堆排序忽略第一个元素
153         array_unshift($arr,0);
154 
155         //获取最后一个非叶子结点
156         $i = $last>>1;
157         //整理成大顶堆,最大的数整到堆顶,并将最大数和堆尾交换,
158         //并在之后的计算中忽略数组后端的最大数(last),直到堆顶(last=堆顶)
159         while(true){
160             adjustNode($i,$last,$arr);
161             if($i>1){
162                 //移动节点指针,遍历所有非叶子节点
163                 $i--;
164             }else{
165                 //临界点last=1,即所有排序完成
166                 if($last == 1)break;
167                 //当i为1时表示每一次的堆整理都将得到最大数(堆顶,$arr[1]),重复在根节点调整堆
168                 swap($arr[$last],$arr[1]);
169                 //在数组尾部按大小顺序保留最大数,定义临界点$last,以免整理堆时重新打乱数组后面已排序好的元素
170                 $last--;
171             }
172         }
173         array_shift($arr);
174     }
175 
176     //整理当前节点($n),临界点$len之后为已排序的元素
177     function adjustNode($n,$last,&$arr){
178         $l = $n<<1;    //$n的左孩子
179         if(!isset($arr[$l]) || $l > $last)return ;
180         $r = $l + 1;
181         //如果右孩子比左孩子大,则让父节点的右孩子比
182         if($r <= $last && $arr[$r] > $arr[$l])$l = $r;
183         //如果其中子节点$l比父节点$n大,则与父节点$n交换
184         if($arr[$l] > $arr[$n]){
185             //子节点($l)的值与父节点($n)的值交换
186             swap($arr[$l],$arr[$n]);
187             //交换后父节点($n)的值($arr[$n])可能还小于原子节点($l)的子节点的值,所以还需对原子节点($l)的子节点进行调整,用递归实现
188             adjustNode($l,$last,$arr);
189         }
190     }
191 
192     //交换两个值
193     function swap(&$a,&$b)
194     {
195             $a=$a ^ $b;
196             $b=$a ^ $b;
197             $a=$a ^ $b;
198     }

posted @ 2017-02-05 15:00  zeoo  阅读(267)  评论(0)    收藏  举报