php 数组(2)

数组排序算法

  冒泡排序,是一种计算机科学领域的较简单的排序算法。它重复地访问要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们减缓过来。走访数列的工作室重复的进行直到没有再需要交换,也就是说该数列已经排序完成

  思路:

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

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

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

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

$arr = array(1,5,3,6,2,,9,8,7,4);
for($i = 0,$len = count($arr);$i < $len;$i++){
    for($j = 0;$j < $len - 1 - $i;$j++){
        if($arr[$j] > $arr[$j + 1]){
            $temp = $arr[$j];
            $arr[$j] = $arr[$j+1];
            $arr[$j+1] = $temp;
        }
    }
}

 

-----

选择排序,是一种简单直观的排序算法,它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完,选择排序是不稳定的排序方法(如:序列[5,5,3]第一次就将第一个[5]与[3]交换,导致第一个5移动到第二个5后面)

思路:

  假设第一个元素为最小元素,记下下标

  寻找右侧剩余的元素,如果有更小的重新记下最新的下标

  如果有新的最小的,交换两个元素

  往右重复以上的步骤,知道元素本身是最后一个

$arr = array(1,5,3,6,2,,9,8,7,4);
// 确定要交换多少次,一次只能找到一个最小的,需要找数组长度对应的次数
for($i = 0,$len = count($arr);$i < $len;$i++){
    // 假设当前第一个已经排好序
    $min = $i; // 当前第一个数时最小的
    // 比较当前元素与选定的最小的元素
    for ($j = $i + 1;$j < $len;$j++){
        if($arr[$j] < $arr[$min]){
        // 说明当前指定的 $min 不合适
            $min = $j;
        }
    }
    // 交换当前选定的值与实际最小的元素值
    if($min != $i){
        $temp = $arr[$i];
        $arr[$i] = $arr[$min];
        $arr[$min] = $temp;
    }
}
echo '<pre>';
print_r($arr);

 

-----

插入排序,基本操作就是讲一个数据插入到已经排好序的有序数据中,从而得到一个新的,个数加一的有序数据,算法适用于少量数据的排序,是稳定的排序方法,插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就指包含这一元素(即待插入元素)。在第一部分排序完成后,再讲这个最后元素插入到已排好序的第一部分中。

思想:每步将一个待 排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止

  设置监视哨 r[0],将待插入记录的值赋值给 r[0];

  设置开始查找的位置 j;

  在数组中进行搜索,搜索中将第 j 个记录后移,直至 r[0].key>=r[j].key 为止;

  将 r[j+1] 的位置上

 

  认定第一个元素已经排好序

  取出第二个元素,作为待插入数据

  与已经排好序的数组的最右侧元素开始进行比较

  如果后面的小于前面的:说明前面已经排好序的那个数组元素不在对的位置(向后移一个),然后让新的元素填充进去(继续向前比:高级)

  重复前面的步骤:直到当前元素插入到对的位置,直到所有的数组元素都插入到对的位置

$arr = array(4,7,6,8,3,1,5,9,);
// 确定要插入多少回(假设一个数组一次性插入到对的位置,同时第一位置是假设对的)
for($i = 1,$len = count($arr);$i < $len;$i++){
    // 取出当前要插入的元素的值
    $temp = $arr[$i];
  // 标记:默认说明当前要插入的数组的位置是对的
  $change = false; // 让该数据与前面已经排好序的数组元素重复比较(挨个比较),直到的位置(交换) for($j = $i - 1;$j >= 0;$j--){ // 比较 if($arr[$j] > $temp){ // 说明当前要插入的元素,比前面的已经排好序的元素的值要小:交换位置 $arr[$j + 1] = $arr[$j]; // $arr[$j] = $temp;
       // 说明前面顺序的数组元素有不合适的位置
       $change = true; }else{ // 说明当前待插入元素,不前面的元素要大:说明位置正确 break; } }
  //
  if($change){
    // 有数据移动:站错位置
    $arr[$j + 1] = $temp;
} echo '<pre>'; print_r($arr);

 

-----

快速排序,是对冒泡排序的一种改进,通过一趟排序将要排序的数据分割成独立的两个部分,其中一部分的所有数据都比另外一部分的所有数据都要笑,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

设要排序的数组是 A[0]......A[N - 1],首先任意选取一个数据(通常选用数组的第一个数),作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动

  从数组中选出一个元素(通常第一个),作为参照对象

  定义两个数组,将目标数组中剩余的元素与参照元素挨个比较:小的放到一个数组,大的放到另外一个数组

  第二步执行完后,前后的数组顺序不确定,但是确定了自己的位置

  将得到的小数组按照第1到第3部重复操作(子问题)

  回溯最小数组(一个元素)

$arr = array(1,5,6,3,4,9,8,7,2);
function quick_sort($arr){
    // 递归出口
    $len count($arr);
    if(len <= 1) return $arr;
    // 取出某个元素,然后将剩余的数组元素,分散到两个不同的数组中
    $left = $right = array();
    for($i = 1;$i < $len;$i++){
        // 第一个元素作为元素
        // 比较:小的放left中,大的放入right 中
        if($arr[$i] < $arr[0]){
            $left[] = $arr[$i];
        }else{
            $right[] = $arr[$i];
        }
    }
    $left = quick_sort($left);
    $right = quick_sort($right);
    return array_mergr($left,(array)$arr[0],$right);
}
echo '<pre>';
print_r(quick_sort($arr));

 

-----

归并排序,是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列有序。若将两个有序表合并成一个有序表,称为二路归并

$arr1 = array(1,5,9);
$arr3 = array(2,4,8);
// 取出一个空数组用于归并空间
$arr3 = array();
while(count($arr1) && count($arr2)){
    // 只要$arr1 和 $arr2里面还有元素,就进行循环
    // 取出每一个数组的第一个元素:进行比较
    $arr3[] = $arr1[0] < $arr2[0] ? array_shift($arr1) : array_shift($arr2);
}
print_r(array_merge($arr3,$arr1,$arr2));

 

  将数组拆分成两个数组

  重复上步骤将数组拆分成最小单元

  申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

  设定两个指针,最初位置分别为两个已经排序序列的起始位置

  比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  重复步骤3直到某一指针超出序列尾

  将另一序列剩下的所有元素直接复制到合并序列尾

$arr = array(1,4,7,2,5,8,3,6,9);
function mege_sort($arr){
    // 递归出口
    $len = count($arr);
    if($len <= 1) return $arr;
    
    $middle = floor($len / 2);
    $left = array_slice($arr,0,$middle);
    $right = array_slice($arr,$middle);

    // 递归点:$left  $right 都没有排好序,而且可能是多个元素的数组
    $left = mege_sort($left);
    $right = mege_sort($right);

    $m = array();
    while(count($left) && count($right)){
        // 只要$left和 $right里面还有元素,就进行循环
        // 取出每一个数组的第一个元素:进行比较
        $m[] = $left[0] < $right[0] ? array_shift($left) : array_shift($right);
    }
    return array_merge($m,$left,$right);
}
print_r(merge_sort($arr));

 

 -----

查找算法

  含义:查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算。查找算法是指实现查找过程对应的代码结

 

顺序查找:也成为线型查找,从数据结构线型表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值比较,若相等则表示查找成功,若扫描结束没有找到关键字等于给定的值的结点,表示查找失败

$arr = array(52,4,6,1,3,82,13,9,6,313);
function check_order($arr,$num){
    for($i = 0,$len = cout($arr);$i < $len;$i++){
        if($arr[$i] == $num){
            return $i;
        }
    }
    return false;
}
varr_dump(check_order($arr,5));

 

二分查找:要求线型表中的结点按关键字值升序或降序排序,用给定值与中间结点的关键字比较,中间结点把线型表分成两个子表,若相等则表示成功;若不相等,再根据给定的值与该中间结点关键字的比较结果确定下一步查找那个子表,这样递归进行,直到查找到货查找结束发现表中没有相等的结点

$arr = array(52,4,6,1,3,82,13,9,6,313);
$res = 5;
function check_break($arr,$res){
    // 得到数组边界
    $right = count($arr);
    $left = 0;
    // 循环匹配
    whilr($left <= $right){
        // 得到中间位置
        $middle = floor(($right + $left) / 2);
        // 匹配数据
        if($arr[$middle] == $res){
            return $middle + 1;
        }
        // 没有找到
        if($arr[$middle] < $res){
        
            $left = $middle +1;
        }else{
        
            $right = $middle + 1;
        }
        
    }
    return false;
}
var_dump(check_break($arr,$res));

 

 

-----

 

posted @ 2018-11-21 18:34  SilentKiller  阅读(199)  评论(0编辑  收藏  举报