PHP算法之四大基础算法

page_img_url

前言

虽然工做中,你以为本身并无涉及到算法这方面的东西,可是算法是程序的核心,一个程序的好与差,关键是这个程序算法的优劣,因此对于冒泡排序、插入排序、选择排序、快速排序这四种基本算法,我想仍是要掌握的。算法

冒泡排序法

冒泡排序大概的意思是依次比较相邻的两个数,而后根据大小作出排序,直至最后两位数。因为在排序过程当中老是小数往前放,大数日后放,至关于气泡往上升,因此称做冒泡排序。

冒泡是从前日后冒,因此,每轮比较的次数也是逐渐减小的,最后一个数不用比较,其时间复杂度为O(n²),算法以下:数组

/**
 * 冒泡排序算法
 * @param array $arr
 * @return array
 */
function bubble_sort($arr) {
    // 判断参数是否为数组,且不为空
    if (!is_array($arr) || empty($arr)) {
        return $arr;
    }
    // 循环须要冒泡的轮数
    for ($i = 1, $len = count($arr); $i < $len; $i++) {
        // 循环每轮须要比较的次数
        for ($j = 0; $j < $len - $i; $j++) {
            // 大的数,交换位置,日后挪
            if ($arr[$j] > $arr[$j + 1]) {
                $temp = $arr[$j + 1];
                $arr[$j + 1] = $arr[$j];
                $arr[$j] = $temp;
            }
        }
    }
    return $arr;
}

选择排序法

选择排序的原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,而后,再从剩余未排序元素中继续寻找最小(大)元素,而后放到已排序序列的末尾;以此类推,直到全部元素均排序完毕。

选择是每一次从假定一个最小值的位置,而后用假定最小值和后面的值依次比较,找到实际的最小值来放到假定最小值的位置上,其时间复杂度也为O(n²),算法以下:优化

/**
 * 选择排序法
 * @param array $arr
 * @return array
 */
function select_sort($arr) {
    // 判断参数是否为数组,且不为空
    if (!is_array($arr) || empty($arr)) {
        return $arr;
    }
    $len = count($arr);
    for ($i = 0; $i < $len - 1; $i++) {
        // 假设最小数的位置
        $min = $i;
        // 用假设的最小数和$i后面的数循环比较,找到实际的最小数
        for ($j = $i + 1; $j < $len; $j++) {
            // 后面的数比假设的最小数小,替换最小数
            if ($arr[$min] > $arr[$j]) {
                $min = $j;
            }
        }
        // 假设的最小数和实际不符,交换位置
        if ($min != $i) {
            $temp = $arr[$min];
            $arr[$min] = $arr[$i];
            $arr[$i] = $temp;
        }
    }
    return $arr;
}

插入排序法

插入排序的原理:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到所有记录插入完成为止。

插入排序法是先将排序元素的前两个元素排序,而后将第三个元素插入已经排序好的两个元素中,因此这三个元素仍然是从小到大排序,接着将第四个元素插入,重复操做直到全部元素都排序好;其时间复杂度一样为O(n²),算法以下:ui

/**
 * 插入排序法
 * @param array $arr
 * @return array
 */
function insert_sort($arr) {
    // 判断参数是否为数组,且不为空
    if (!is_array($arr) || empty($arr)) {
        return $arr;
    }
    $len = count($arr);
    for ($i = 1; $i < $len; $i++) {
        // 当前须要比较的临时数
        $tmp = $arr[$i];
        // 循环比较临时数所在位置前面的数
        for ($j = $i - 1; $j >= 0; $j--) {
            // 前面的数比临时数大,则交换位置
            if ($arr[$j] > $tmp) {
                $arr[$j + 1] = $arr[$j];
                $arr[$j] = $tmp;
            }
        }
    }
    return $arr;
}

快速排序法

快速排序法是对冒泡排序的一种改进。他的基本原理是:经过一趟排序将待排记录分割成独立的两部分,其中一部分的关键字均比另外一部分记录的关键字小,则可分别对这两部分记录继续进行快速排序,整个排序过程能够递归进行,以达到整个序列有序的目的。

快速排序法是从数列中挑出第一个数(最后一个数)做为基准元素,而后循环全部数,和基准书比较分为左右两列,而后重复这样的步骤继续划分为左右两列,算法以下:url

/**
 * 快速排序法
 * @param array $arr
 * @return array
 */
function quick_sort($arr) {
    // 判断参数是否为数组,且不为空
    if (!is_array($arr) || empty($arr)) {
        return $arr;
    }
    // 数组长度为1中止排序
    $len = count($arr);
    if ($len == 1) {
        return $arr;
    }
    // 声明左右两个空数组
    $left = $right = [];
    // 循环遍历,把第一个元素当作基准数
    for ($i = 1; $i < $len; $i++) {
        // 比较当前数的大小,并放入对应的左右数组
        if ($arr[$i] > $arr[0]) {
            $right[] = $arr[$i];
        } else {
            $left[] = $arr[$i];
        }
    }
    // 递归比较
    $left = quick_sort($left);
    $right = quick_sort($right);
    // 左右两列以及基准数合并
    return array_merge($left, [$arr[0]], $right);
}

使用方法

声明一个待排序的数组,而后调用对应的排序方法便可获得返回的排序好的数组;说明一下,我这里的排序设计都是递增的,若是须要递减,须要修改一下排序算法的比较替换符就行。spa

// 待排序数组
$arr = [1, 4, 5, 9, 3, 8, 6];
// 调用排序方法
$sort_arr = bubble_sort($arr);
// 输出打印
print_r($sort_arr);

分析算法

一般,对于一个给定的算法,咱们要作两项分析:第一是从数学上证实算法的正确性,这一步主要用到形式化证实的方法及相关推理模式,如循环不变式、数学概括法等。而在证实算法是正确的基础上,第二步就是分析算法的时间复杂度。算法的时间复杂度反映了程序执行时间随输入规模增加而增加的量级,在很大程度上能很好反映出算法的优劣与否。还有咱们一般说的:算法优化无非就是以时间换空间,以空间换时间,通常这二者是不可兼得。设计

结束语

实现一个程序,确定是有多种算法的,你们有其余想说的,均可以留言和我交流,谢谢!若有问题,也欢迎指出,我会及时改正,谢谢!code

相关文章
相关标签/搜索