算法-排序-php(一)

191 阅读1分钟

php提供的排序

$arr = [1,5,4,3,20,12,59];
//按照某种升序进行排序
sort($arr,SORT_NUMERIC);
//按照某中降序进行排序
rsort($arr,SORT_NUMERIC);
//排序之后保有原来的索引关系
asort($arr,SORT_NUMERIC);
arsort($arr,SORT_NUMERIC);
print_r($arr);

$arr = [
    [
        "age"=>10,
        "name"=>30,
    ],
    [
        "age"=>10,
        "name"=>20,
    ],
    [
        "age"=>12,
        "name"=>10
    ]
];
//usort 排序
usort($arr,function($a,$b){
    if($a["age"] > $b["age"]) {
        return 1 ;
    }else if ($a["age"]<$b["age"]){
        return -1;
    }else {
        if($a["name"] > $b["name"]) {
            return 1;
        }else if($a["name"] < $b["name"]) {
            return -1;
        }
    }
    return 0;
});
array_multisort($arr,SORT_ASC,array_column($arr,"age"),SORT_ASC,array_column($arr,"name"));

冒泡排序

  1. 先从外部开始进行循环
  2. 然后和内部的数据一个一个进行比较 如果比内部数据大的话 就进行交换
  3. 临界点 外部从0开始 循环到最后一个数
  4. 内部从0开始 因为每循环一次最大的数字就已经在后面了,因此不需要再次进行循环
  5. 优化逻辑,如果某一次内部循环,一次都没有进行交换的话,说明已经是有序的了,就不再需要进行排序
$length = count($arr);
for ($i = 0; $i < $length-1; $i++) {
    $flag = true;
    for ($j = 0; $j < $length-1-$i; $j++) {
        if ($arr[$j] > $arr[$j + 1]) {
            $flag = false;
            $temp = $arr[$j];
            $arr[$j] = $arr[$j + 1];
            $arr[$j + 1] = $temp;
        }
    }
    if($flag == true) {
        break;
    }
}

选择排序

  1. 选择排序 先假定当前的循环的值是最小的$min[index],
  2. 循环外测 从0开始循环
  3. 循环内测 每次都从i开始循环 然后将arr[$min]和当前的数据进行比较,如果小于的话,就将index进行交换一次循环完成了,在外层就将数据进行交换
  4. 如果内层循环min比没有进行变化 则认为已经是有序的了 则不必进行处理
$arr = [1, 5, 4, 3, 20, 12, 59];
$length = count($arr) - 1;
for ($i = 0; $i < $length - 1; $i++) {
    $min = $i; // 假设当前的key为最小的值
    for ($j = $i; $j < $length; $j++) {
        if ($arr[$min] > $arr[$j]) {
            $min = $j;
        }
    }
    $temp = $arr[$min];
    $arr[$min] = $arr[$i];
    $arr[$i] = $temp;
}
print_r($arr);
exit;

插入排序

  1. 将前面的序列都当为有序的 然后的序列都是无序的
  2. 循环找到位置之后,插入数据
  3. 先获取到5(i=1) 将获取到的和前一个进行比较(因为前面的是有序的,只需要和最后一个进行比较,即时当前的i-1)
  4. 第一步 即 1 5 进行比较 发现小于 并且循环条件到了 退出循环 将arr[j+1] =$temp 第一个则不需要交换位置
  5. 第二部 即 5 4 进行比较 发现5大于4 交换位置 然后 1 4 进行比较 小于 循环条件到了 退出循环 找到了位置,然后将位置的值和前面保存的值相互交换
$arr = [1, 5, 4, 3, 20, 12, 59];
$len = count($arr);
for ($i = 1; $i < $len; $i++) {
    $temp = $arr[$i];
    for ($j = $i - 1; $j >= 0 && $arr[$j] > $temp; $j--) {
            $arr[$j + 1] = $arr[$j];
    }
    $arr[$j + 1] = $temp;
}
print_r($arr);
exit;

希尔排序

  1. 先按照因子将数组分为多少组,这里使用count(length)/2 进行分组
  2. 然后将每组的数据进行比较,使用冒泡或者选择排序进行对数组排序
$arr = [1, 3, 2, 5, 12, 10, 20, 15];
$length = count($arr);
//分组 数据逐渐减少
for ($cap = (int)($length / 2); $cap > 0; $cap = (int)($cap / 2)) {
  //一共有多少组
  for ($k = $cap; $k < $length; $k++) {
    //每组的数组进行比较
    for ($j = $k - $cap; $j >= 0; $j = $j - $cap) {
      if ($arr[$j] > $arr[$j + $cap]) {
        $temp = $arr[$j];
        $arr[$j] = $arr[$j + $cap];
        $arr[$j + $cap] = $temp;
      }
    }
  }
}

$arr = [1, 3, 2, 5, 12, 10, 20, 15];

for ($cap = (int)($length / 2); $cap > 0; $cap = (int)($cap / 2)) {
  for ($k = $cap; $k < $length; $k++) {
    //选择排序  假设当前是最小的
    $temp = $arr[$k];
    //如果当前的小于的话 就需要找到需要插入的位置
    while ($k - $cap >= 0 && $temp < $arr[$k - $cap]) {
      $arr[$k] = $arr[$k - $cap];
      $k = $k - $cap;
    }
    $arr[$k] = $temp;
  }
}

print_r($arr);