blog/_posts/算法/algorithm-demo.md
2024-08-21 09:15:38 +08:00

2.9 KiB
Raw Permalink Blame History

title date tags
👶一些简单算法PHP实现 2024-08-16
算法

这里介绍一些简单的算法,包括:冒泡排序、快速排序、二分查找、二叉树的遍历、二叉树的层次遍历、二叉树的前序、中序、后序遍历,一些简单的实现。

冒泡排序

function bubble_sort($arr)
{
    $n = count($arr);
    for ($i = 0; $i < $n; $i++) {
        for ($j = 0; $j < $n - $i - 1; $j++) {
            if ($arr[$j] < $arr[$j + 1]) {
                [$arr[$j], $arr[$j + 1]] = [$arr[$j + 1], $arr[$j]];
            }
        }
    }
    return $arr;
}

冒泡排序过程的详细步骤,假设我们有一个数组 [64, 34, 25, 12, 22, 11, 90] 需要进行升序排序:

  1. 第一轮冒泡:

    • 比较 64 和 3464 > 34交换它们的位置数组变为 [34, 64, 25, 12, 22, 11, 90]
    • 比较 64 和 2564 > 25交换它们的位置数组变为 [34, 25, 64, 12, 22, 11, 90]
    • 比较 64 和 1264 > 12交换它们的位置数组变为 [34, 25, 12, 64, 22, 11, 90]
    • 比较 64 和 2264 > 22交换它们的位置数组变为 [34, 25, 12, 22, 64, 11, 90]
    • 比较 64 和 1164 > 11交换它们的位置数组变为 [34, 25, 12, 22, 11, 64, 90]
    • 比较 64 和 9064 < 90不需要交换这一轮结束

    第一轮冒泡后,最大的数 90 被“冒泡”到了数组的最后一位。

  1. N轮冒泡

对除了最后一个元素之外的所有元素进行上述相同的比较和交换操作,这一轮结束后,次大的数 64 被放到了倒数第二位。重复上述过程,每一轮都将未排序部分的最大值“冒泡”到已排序部分的末尾。每一轮冒泡都会使未排序部分的长度减少 1当整个数组遍历一遍而没有任何元素交换时表示数组已经排序完成。

经过多轮冒泡后,数组 [64, 34, 25, 12, 22, 11, 90] 逐渐被排序为 [11, 12, 22, 25, 34, 64, 90]。

冒泡排序的平均时间复杂度和最坏时间复杂度都是 O(n^2),其中 n 是数组的长度。因此,它不适合对大数据集进行排序

快速排序

function quick_sort(array $array)
{
    if (count($array) < 2) {
        return $array;
    }
    reset($array);
    $pivot_key = key($array);
    $pivot     = array_shift($array);
    $left      = $right = [];
    foreach ($array as $k => $v) {
        if ($v > $pivot) {
            $right[$k] = $v;
        } else {
            $left[$k] = $v;
        }
    }
    return array_merge(quick_sort($left), [
        $pivot_key => $pivot
    ], quick_sort($right));
}

快速排序过程的简化描述

  1. 假设数组为 [8, 4, 5, 7, 1, 3, 6, 2]
  2. 选择第一个元素 8 作为基准
  3. 分区后数组变为 [4, 1, 3, 2, 8, 5, 7, 6]8 在中间)
  4. 递归地对 8 左边的子数组 [4, 1, 3, 2] 和右边的子数组 [5, 7, 6] 进行排序
  5. 最终数组变为 [1, 2, 3, 4, 5, 6, 7, 8]