经典算法


算法(分类:比较和非比较):原理 复杂度  稳定性 ==>各自的区别==>代码实现

    

bubble:        相邻比较       On2     稳定的       一步步挪动 

quick_sort:    分治法         Onlgn  不稳定的  递归+回归

insert_sort:一趟找到       On2     稳定的  固定元素找位置

select_sort:  一趟找到       On2     不稳定的    固定位置找元素

Binary-Search  分治法       Olgn  有序队列

代码实现:基本上会有两次循环 i j,循环内部会有判断 j,判断里交换值 j,

说明:排序算法有很多,包括插入排序冒泡排序堆排序归并排序选择排序计数排序基数排序桶排序快速排序等。插入排序,堆排序,选择排序,归并排序和快速排序,冒泡排序都是比较排序,它们通过对数组中的元素进行比较来实现排序,其他排序算法则是利用非比较的其他方法来获得有关输入数组的排序信息。



插入排序:直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。

http://www.cnblogs.com/kkun/archive/2011/11/23/2260265.html


插入排序算法的运作如下:(从后往前)

⒈ 从第一个元素开始,该元素可以认为已经被排序

⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描

⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置

⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

⒌ 将新元素插入到下一位置中

⒍ 重复步骤2

     

function insertSort(&$arr){
//先默认第一个下标为0的数是排好的数
for($i=1;$i<count($arr);$i++){
  //确定插入比较的数
  $insertVal=$arr[$i];
  //确定与前面比较的数比较
  $insertIndex=$i-1;


  //表示没有找到位置
  while($insertIndex>=0 && $insertVal<$arr[$insertIndex]){
  //把数后移
  $arr[$insertIndex+1]=$arr[$insertIndex];
  $insertIndex--;
  }
  //插入(给$insertval找到位置了)
  $arr[$insertIndex+1] = $insertVal;
  }
}


选择排序算法的运作如下:

http://blog.youkuaiyun.com/cjf_iceking/article/details/7914554

  1. 它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,

  2. 存放在序列的起始位置,

  3. 直到全部待排序的数据元素排完。



      function select_sort($arr){


        $count = count($arr);


        for ($i=0; $i < $count-1; $i++) { 


          $min = $i;


          for ($j=$i+1; $j < $count; $j++) {    //$j加1了,那么$i的count就要减1


              if ($arr[$min] < $arr[$j]) {
                  $min = $j;
              }


          }


          if ($min != $i) {
              $tmp = '';
              $tmp =$arr[$min];
              $arr[$min] = $arr[$i];
              $arr[$i] = $tmp;
          }
        }


        return $arr;


      }



冒泡排序算法的运作如下:(从后往前)

http://www.cnblogs.com/kkun/archive/2011/11/23/2260280.html

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。[1] 


      function bubble($arr){


          $count = count($arr);;


          for ($i=0; $i < $count; $i++) { 
            
              for ($j=$count-1; $j > $i; $j--) { 
                  if ($arr[$j-1] < $arr[$j]) {   //判断,比小的放前面,比大的放后面
                    $tmp = $arr[$j];
                    $arr[$j] = $arr[$j-1];
                    $arr[$j-1] = $tmp;
                  }
                  


              }
          }


          return $arr;


      }



快速排序的算法:http://developer.51cto.com/art/201403/430986.htm

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

//效率较低,容易理解

      function quick_sort($arr){


          $count = count($arr);
          if($count<=1) return $arr;      //回归


          $left = array();
          $right = array();
          $key = $arr[0];


          for ($i=1; $i < $count; $i++) { 
              
              if ($arr[$i] < $key) {
                  
                  $left[] = $arr[$i];


              }else{


                $right[] = $arr[$i];
              }
          }


          $leftArr = quick_sort($left); //递归
          $rightArr = quick_sort($right);
          return array_merge($leftArr,array($key),$rightArr);


      }




  echo '<pre>';


  $old_array=array(3,4,5,6,8,2,12,-1,0);


  $new_array=quick_sort($old_array);


  print_R($new_array);



//不支持重复数组,效率较高


function quick_sort(&$array, $start, $end) {


    if ($start >= $end) return;


    $mid = $start;


    for ($i = $start + 1; $i <= $end; $i++) {


         if ($array[$i] > $array[$mid]) {


             $mid++;


             $tmp = $array[$i];


             $array[$i] = $array[$mid];


             $array[$mid] = $tmp;


         }


    }


    $tmp = $array[$start];


    $array[$start] = $array[$mid];


    $array[$mid] = $tmp;


    quick_sort($array, $start, $mid - 1);


    quick_sort($array, $mid + 1, $end);


}


echo '<pre>';


$arr = array(23,35,4,656,567,658,568,678,7689,2);


quick_sort($arr,0,count($arr)-1);


print_r($arr); 



二分查找

它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,

如 果x<a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。

如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。

如果x=a[n/2]则找到x,算法终止。


//递归版本
function bin_sch($array,$target){
$low = 0;
$high = count($array) - 1;
if($low<=$high){
$mid=intval(($low+$high)/2);
 
if($array[$mid]==$target){
return$mid;
}elseif($target<$array[$mid]){
return bin_sch($array,$low,$mid-1,$target);
}else{
return bin_sch($array,$mid+1,$high,$target);
}
}
return-1;
}



//非递归版本


      function binarySearch2(Array $arr, $target) {
          $low = 0;
          $high = count($arr) - 1;
       
          while($low <= $high) {
              $mid = floor(($low + $high) / 2);  //取中位数
              #找到元素
             if($arr[$mid] == $target) return $mid;
             #中元素比目标大,查找左部
             if($arr[$mid] > $target) $high = $mid - 1;//high往左
             #重元素比目标小,查找右部
             if($arr[$mid] < $target) $low = $mid + 1;//low 往右
         }
         
         #查找失败
         return false;
     }
     



     $arr = array(3,4,5, 17, 9, 11);
     $inx = binarySearch($arr, 11);
     var_dump($inx);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值