ZetCode

PHP Shell 排序算法

最后修改于 2025 年 4 月 16 日

基本定义

算法 是一种逐步解决问题或执行计算的程序。在编程中,算法被实现为函数或方法。

排序 是指将数据按特定顺序排列,通常是升序或降序。有效的排序对于优化其他算法(如搜索操作)至关重要。

常见的排序算法包括

Shell 排序概述

Shell 排序是插入排序的一种优化,它允许交换相隔较远的项。它的工作原理是按特定的间隔对元素进行排序,然后减小间隔,直到间隔变为 1。

该算法由 Donald Shell 于 1959 年发明。它的时间复杂度根据使用的间隔序列而变化,通常在 O(n) 和 O(n²) 之间。

Shell 排序实现

这是一个 PHP 中对数字数据的 Shell 排序的基本实现

shell_sort.php
<?php

function shellSort(array $arr): array {
    $n = count($arr);
    $gap = floor($n / 2);
    
    while ($gap > 0) {
        for ($i = $gap; $i < $n; $i++) {
            $temp = $arr[$i];
            $j = $i;
            
            while ($j >= $gap && $arr[$j - $gap] > $temp) {
                $arr[$j] = $arr[$j - $gap];
                $j -= $gap;
            }
            
            $arr[$j] = $temp;
        }
        
        $gap = floor($gap / 2);
    }
    
    return $arr;
}

$numbers = [12, 34, 54, 2, 3];
$sorted = shellSort($numbers);
print_r($sorted);

此实现将数字按升序排序。间隔从数组长度的一半开始,每次迭代减半,直到达到 0。

对文本数据进行排序

Shell 排序也可以按字母顺序对字符串进行排序。 这是一个例子

shell_sort_strings.php
<?php

function shellSortStrings(array $arr): array {
    $n = count($arr);
    $gap = floor($n / 2);
    
    while ($gap > 0) {
        for ($i = $gap; $i < $n; $i++) {
            $temp = $arr[$i];
            $j = $i;
            
            while ($j >= $gap && strcmp($arr[$j - $gap], $temp) > 0) {
                $arr[$j] = $arr[$j - $gap];
                $j -= $gap;
            }
            
            $arr[$j] = $temp;
        }
        
        $gap = floor($gap / 2);
    }
    
    return $arr;
}

$names = ["apple", "orange", "banana", "pear"];
$sortedNames = shellSortStrings($names);
print_r($sortedNames);

此版本使用 strcmp 比较字符串。 它将数组按升序字母顺序排序。

降序排序

要按降序排序,我们只需反转比较条件

shell_sort_desc.php
<?php

function shellSortDesc(array $arr): array {
    $n = count($arr);
    $gap = floor($n / 2);
    
    while ($gap > 0) {
        for ($i = $gap; $i < $n; $i++) {
            $temp = $arr[$i];
            $j = $i;
            
            while ($j >= $gap && $arr[$j - $gap] < $temp) {
                $arr[$j] = $arr[$j - $gap];
                $j -= $gap;
            }
            
            $arr[$j] = $temp;
        }
        
        $gap = floor($gap / 2);
    }
    
    return $arr;
}

$numbers = [12, 34, 54, 2, 3];
$sortedDesc = shellSortDesc($numbers);
print_r($sortedDesc);

唯一的改变是将比较运算符从 > 更改为 <。 这使得算法按降序排序。

Shell 排序 vs 快速排序

让我们将 Shell 排序与快速排序进行比较,快速排序是最快的排序算法之一。 我们将使用一个大型数组来对两者进行基准测试。

sort_benchmark.php
<?php

function quickSort(array $arr): array {
    if (count($arr) <= 1) {
        return $arr;
    }
    
    $pivot = $arr[0];
    $left = $right = [];
    
    for ($i = 1; $i < count($arr); $i++) {
        if ($arr[$i] < $pivot) {
            $left[] = $arr[$i];
        } else {
            $right[] = $arr[$i];
        }
    }
    
    return array_merge(quickSort($left), [$pivot], quickSort($right));
}

// Generate large array
$largeArray = range(1, 10000);
shuffle($largeArray);

// Shell Sort benchmark
$start = microtime(true);
shellSort($largeArray);
$shellTime = microtime(true) - $start;

// Quick Sort benchmark
$start = microtime(true);
quickSort($largeArray);
$quickTime = microtime(true) - $start;

echo "Shell Sort time: " . number_format($shellTime, 6) . " seconds\n";
echo "Quick Sort time: " . number_format($quickTime, 6) . " seconds\n";

在典型运行中,对于大型数据集,快速排序将比 Shell 排序更快。 但是,Shell 排序在处理中等大小的数组或内存受限时具有优势,因为它是一种就地排序算法。

何时使用 Shell 排序

来源

维基百科上的 Shell 排序

本教程介绍了 PHP 中的 Shell 排序算法,并提供了数字和文本数据的示例,包括与快速排序的性能比较。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 PHP 教程