.pyi.pydPythonDLL(动态链接库)

一、为什么使用?

  1. .pyd 的优势:
    性能提升:C 扩展比纯 Python1-2 倍(如循环密集型任务)。
    代码保护:反编译难度高,适用于商业闭源项目。
    跨语言集成:复用 C/C++ 生态的成熟库。
  2. .pyi 的优势:
    开发效率:IDE 自动补全和类型提示减少编码错误。
    文档化接口:明确模块功能,尤其适用于无源码的第三方库。

二、.pyd 文件的创建与使用

  1. 通常通过以下两种方式创建:
  • Cython(推荐):

    1. 编写 Python 代码:例如 example.py

    2. 转换为 .pyx 文件:将 .py 文件重命名为 .pyx,或直接编写 Cython 代码。

    3. 编写 setup.py

      from setuptools import setup
      from Cython.Build import cythonize
      setup(ext_modules=cythonize("example.pyx"))
      
    4. 编译生成 .pyd:执行命令 python setup.py build_ext --inplace,生成 example.pyd

  • 手动编写C/C++扩展:

    1. 编写 C/C++ 代码,并遵循 Python C API 规范(如函数注册和模块定义)。
    2. 使用 setuptools 编译,类似Cython的流程。
  1. 使用方法:

    • 导入模块:将 .pyd 文件放在 Python 搜索路径(如当前目录或 sys.path 包含的路径),直接 import example 即可调用其函数。
    • 注意事项:
      • 版本兼容性:.pyd 需与 Python 版本、操作系统架构(32/64 位)完全匹配。
      • 依赖处理:若依赖其他 DLL,需将路径添加到环境变量或使用 os.add_dll_directory()
  2. 使用场景:

    • 性能优化:C/C++ 编译的代码比纯 Python 快,适合计算密集型任务(如科学计算)。
    • 代码保护:.pyd 是二进制文件,难以反编译,适合保护核心算法。
    • 集成底层库:调用现有C/C++库或硬件接口。

三、.pyi 文件的创建与使用

  1. 创建方法(.pyi 是类型提示存根文件,提供静态类型信息)
  • 手动编写:根据模块接口定义类型,例如:

    # example.pyi
    def add(a: int, b: int) -> int: ...
    
  • 自动生成:使用工具如 mypystubgenpyright,根据代码或 .pyd 生成类型提示。

  1. 使用方法
  • 与模块同名:将.pyi文件与对应的 .py.pyd文件放在同一目录,IDE 和类型检查工具(如 mypy)会自动识别。

  • 调试与补全:在 PyCharm、VS Code 等 IDE 中,.pyi 可提供代码补全和类型检查支持。

  1. 使用场景
  • 静态类型检查:帮助发现类型错误(如参数类型不匹配)。
  • IDE 支持:为 .pyd 等二进制模块提供可读的接口文档。
  • 代码维护:明确模块的输入输出类型,提升协作效率。

四、常见问题

  1. .pyd 导入失败
    • 原因:Python 版本或架构不匹配、依赖缺失。
    • 解决:检查编译环境,确保路径正确。
  2. .pyi 类型提示无效:
    • 原因:文件命名错误或类型定义不匹配。
    • 解决:确保 .pyi 与模块同名,且函数签名一致

五、工具推荐

  1. Cython:生成.pyd的核心工具。
  2. mypy/stubgen:生成和验证.pyi文件。
  3. PyInstaller:打包.pyd为独立可执行文件。

六、示例01(使用Cython

  1. 文件目录结构:
sort_demo/
├── cython_sort.pyx  # Cython 源码
├── setup.py         # 编译脚本
├── cython_sort.pyd  # 编译后生成
└── cython_sort.pyi  # 类型提示
  1. cython_sort.pyx

# cython_sort.pyx
import numpy as np
cimport numpy as cnp
from libc.stdlib cimport qsort
from enum import IntEnum  # 添加这行

# Cython 内部使用的枚举
cdef enum CSortType:
    BUBBLE_SORT = 0
    QUICK_SORT = 1
    COUNTING_SORT = 2
    RADIX_SORT = 3

# Python 可见的枚举类
class SortType(IntEnum):
    BUBBLE_SORT = CSortType.BUBBLE_SORT
    QUICK_SORT = CSortType.QUICK_SORT
    COUNTING_SORT = CSortType.COUNTING_SORT
    RADIX_SORT = CSortType.RADIX_SORT

# 修正后的快速排序比较函数 - 添加 'nogil' 和 'noexcept'
cdef int compare(const void *a, const void *b) noexcept nogil:
    cdef int a_val = (<int*>a)[0]
    cdef int b_val = (<int*>b)[0]
    return a_val - b_val

# 排序主函数
def sort(arr: list[int], sort_type: SortType) -> list[int]:
    cdef cnp.ndarray[cnp.int_t, ndim=1] np_arr = np.array(arr, dtype=np.int32)
    
    if sort_type == SortType.BUBBLE_SORT:
        return bubble_sort(np_arr).tolist()
    elif sort_type == SortType.QUICK_SORT:
        return quick_sort(np_arr).tolist()
    elif sort_type == SortType.COUNTING_SORT:
        return counting_sort(np_arr).tolist()
    elif sort_type == SortType.RADIX_SORT:
        return radix_sort(np_arr).tolist()
    else:
        raise ValueError("未知排序类型")

# 冒泡排序(Cython 优化版)
cdef cnp.ndarray bubble_sort(cnp.ndarray[cnp.int_t, ndim=1] arr):
    cdef int n = arr.shape[0]
    cdef int *ptr = <int*>cnp.PyArray_DATA(arr)
    cdef int i, j, temp
    
    for i in range(n):
        for j in range(0, n-i-1):
            if ptr[j] > ptr[j+1]:
                temp = ptr[j]
                ptr[j] = ptr[j+1]
                ptr[j+1] = temp
    return arr

# 快速排序(基于标准库 qsort)
cdef cnp.ndarray quick_sort(cnp.ndarray[cnp.int_t, ndim=1] arr):
    cdef int n = arr.shape[0]
    cdef int *ptr = <int*>cnp.PyArray_DATA(arr)
    
    # 在 nogil 块中调用 qsort
    with nogil:
        qsort(ptr, n, sizeof(int), &compare)
    return arr

# 计数排序
cdef cnp.ndarray counting_sort(cnp.ndarray[cnp.int_t, ndim=1] arr):
    cdef int n = arr.shape[0]
    cdef int max_val = np.max(arr)
    cdef cnp.ndarray[cnp.int_t, ndim=1] count = np.zeros(max_val+1, dtype=np.int32)
    cdef cnp.ndarray[cnp.int_t, ndim=1] output = np.empty(n, dtype=np.int32)
    cdef int *arr_ptr = <int*>cnp.PyArray_DATA(arr)
    cdef int *count_ptr = <int*>cnp.PyArray_DATA(count)
    cdef int *out_ptr = <int*>cnp.PyArray_DATA(output)
    cdef int i, idx = 0
    
    # 计数
    for i in range(n):
        count_ptr[arr_ptr[i]] += 1
    
    # 输出
    for i in range(max_val+1):
        for j in range(count_ptr[i]):
            out_ptr[idx] = i
            idx += 1
            
    return output

# 基数排序(支持负数)
cdef cnp.ndarray radix_sort(cnp.ndarray[cnp.int_t, ndim=1] arr):
    cdef int n = arr.shape[0]
    cdef int *ptr = <int*>cnp.PyArray_DATA(arr)
    
    # 处理空数组
    if n == 0:
        return arr
    
    # 查找最小值和最大值
    cdef int min_val = ptr[0]
    cdef int max_val = ptr[0]
    cdef int i
    for i in range(1, n):
        if ptr[i] < min_val:
            min_val = ptr[i]
        if ptr[i] > max_val:
            max_val = ptr[i]
    
    # 创建临时数组
    cdef cnp.ndarray[cnp.int_t, ndim=1] output = np.empty(n, dtype=np.int32)
    cdef int *out_ptr = <int*>cnp.PyArray_DATA(output)
    
    # 处理负数:添加偏移量使所有值为非负
    cdef int offset = 0
    if min_val < 0:
        offset = -min_val
        for i in range(n):
            ptr[i] += offset
        max_val += offset
    
    # 基数排序主循环
    cdef int exp = 1
    cdef int j
    cdef int count[10]  # 声明计数数组
    
    while max_val // exp > 0:
        # 初始化计数数组
        for j in range(10):
            count[j] = 0
        
        # 统计数字出现次数
        for i in range(n):
            j = (ptr[i] // exp) % 10
            count[j] += 1
        
        # 计算累计位置
        for j in range(1, 10):
            count[j] += count[j - 1]
        
        # 根据计数构建输出数组(从后向前保持稳定性)
        for i in range(n-1, -1, -1):
            j = (ptr[i] // exp) % 10
            count[j] -= 1
            out_ptr[count[j]] = ptr[i]
        
        # 将输出数组复制回原数组
        for i in range(n):
            ptr[i] = out_ptr[i]
        
        # 移到下一位数字
        exp *= 10
    
    # 移除偏移量恢复原始值
    if offset > 0:
        for i in range(n):
            ptr[i] -= offset
    
    return arr
  1. setup.py

from setuptools import setup
from Cython.Build import cythonize
import numpy as np

setup(
    ext_modules=cythonize("cython_sort.pyx", 
                          compiler_directives={'language_level': "3"}),
    include_dirs=[np.get_include()]
)
  1. 编译命令

    python setup.py build_ext --inplace
    
  2. cython_sort.pyi (类型提示)

from enum import Enum

class SortType(Enum):
    BUBBLE_SORT: int
    QUICK_SORT: int
    COUNTING_SORT: int
    RADIX_SORT: int

def sort(arr: list[int], sort_type: SortType) -> list[int]: ...
  1. test_demo.py
from cython_sort import sort, SortType
import numpy as np
import time
import random
import sys

# 打印系统信息
print(f"Python版本: {sys.version}")
print(f"操作系统: {sys.platform}")
print(f"处理器: {sys.getwindowsversion().build if sys.platform == 'win32' else '未知'}")

# 生成测试数据
np.random.seed(42)
data_sizes = [1000, 5000, 10000]  # 不同大小的数据集
results = {}

for size in data_sizes:
    print(f"\n{'='*50}")
    print(f"测试数据集大小: {size}")
    print(f"{'='*50}")
    
    data = np.random.randint(0, 10000, size).tolist()
    print(f"原始数据长度:{len(data)}")
    
    # 测试内置排序
    start = time.perf_counter()
    sorted_builtin = sorted(data)
    elapsed_builtin = time.perf_counter() - start
    print(f"Python内置排序耗时: {elapsed_builtin:.6f}秒")
    
    # 测试各种排序算法
    for sort_type in [SortType.BUBBLE_SORT, SortType.QUICK_SORT, 
                      SortType.COUNTING_SORT, SortType.RADIX_SORT]:
        # 复制数据以避免修改原始数据
        test_data = data.copy()
        
        start = time.perf_counter()
        sorted_data = sort(test_data, sort_type)
        elapsed = time.perf_counter() - start
        
        # 验证排序结果
        assert sorted_data == sorted_builtin, f"{sort_type}排序结果验证失败"
        
        type_names = {
            SortType.BUBBLE_SORT: "冒泡排序",
            SortType.QUICK_SORT: "快速排序",
            SortType.COUNTING_SORT: "计数排序",
            SortType.RADIX_SORT: "基数排序"
        }
        
        # 计算相对于内置排序的速度比
        speed_ratio = elapsed_builtin / elapsed if elapsed > 0 else float('inf')
        
        print(f"{type_names[sort_type]}耗时: {elapsed:.6f}秒", 
              f"({speed_ratio:.2f}x {'快于' if speed_ratio > 1 else '慢于'}内置排序)")
        
        # 存储结果用于后续分析
        if sort_type not in results:
            results[sort_type] = []
        results[sort_type].append((size, elapsed))

# 添加测试负数和零的情况
print("\n测试边界情况:")
test_cases = [
    ("负数", [-5, -3, -1, -2, -4]),
    ("零", [0, 0, 0, 0, 0]),
    ("混合", [-5, 0, 5, -3, 3]),
    ("重复", [5, 3, 5, 1, 3, 1]),
    ("有序", [1, 2, 3, 4, 5]),
    ("逆序", [5, 4, 3, 2, 1]),
]

for name, data in test_cases:
    print(f"\n测试用例: {name} - {data}")
    
    # 内置排序
    sorted_builtin = sorted(data)
    
    # 测试各种排序算法
    for sort_type in [SortType.QUICK_SORT, SortType.RADIX_SORT]:
        test_data = data.copy()
        sorted_data = sort(test_data, sort_type)
        
        type_names = {
            SortType.BUBBLE_SORT: "冒泡排序",
            SortType.QUICK_SORT: "快速排序",
            SortType.COUNTING_SORT: "计数排序",
            SortType.RADIX_SORT: "基数排序"
        }
        
        assert sorted_data == sorted_builtin, f"{type_names[sort_type]}在{name}测试中失败"
        print(f"{type_names[sort_type]}结果: {sorted_data}")

# 性能对比图表(可选)
try:
    import matplotlib.pyplot as plt
    
    print("\n生成性能对比图表...")
    plt.figure(figsize=(12, 8))
    
    for sort_type, times in results.items():
        sizes = [size for size, _ in times]
        durations = [time for _, time in times]
        
        type_names = {
            SortType.BUBBLE_SORT: "冒泡排序",
            SortType.QUICK_SORT: "快速排序",
            SortType.COUNTING_SORT: "计数排序",
            SortType.RADIX_SORT: "基数排序"
        }
        
        plt.plot(sizes, durations, 'o-', label=type_names[sort_type])
    
    # 添加内置排序参考线
    builtin_times = [0.0001, 0.0005, 0.001]  # 示例值,实际值会根据运行结果变化
    plt.plot(data_sizes, builtin_times, 'k--', label="Python内置排序")
    
    plt.xlabel('数据量')
    plt.ylabel('耗时 (秒)')
    plt.title('排序算法性能对比')
    plt.legend()
    plt.grid(True)
    plt.yscale('log')  # 对数尺度更好地展示差异
    plt.savefig('sorting_performance.png')
    print("图表已保存为 sorting_performance.png")
    
except ImportError:
    print("\n未安装matplotlib,跳过图表生成")
  1. 测试结果
sorting_performance.png

七、示例02(使用手动C扩展

  1. 文件结构
sort_demo/
├── sort_module.c         # C 扩展源码
├── setup.py             # 编译脚本
├── sort_module.pyd      # 编译后生成
└── sort_module.pyi      # 类型提示文件
  1. sort_module.c (完整实现)
#include "Python.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>

// 排序类型枚举
typedef enum
{
  BUBBLE_SORT = 0,
  QUICK_SORT = 1,
  COUNTING_SORT = 2,
  RADIX_SORT = 3
} SortType;

// 快速排序分区函数
static int partition(int arr[], int low, int high)
{
  int pivot = arr[high];
  int i = low - 1;
  int j;
  for (j = low; j <= high - 1; j++)
  {
    if (arr[j] < pivot)
    {
      i++;
      int temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
    }
  }
  int temp = arr[i + 1];
  arr[i + 1] = arr[high];
  arr[high] = temp;
  return i + 1;
}

// 快速排序主函数
static void quick_sort_impl(int arr[], int low, int high)
{
  if (low < high)
  {
    int pi = partition(arr, low, high);
    quick_sort_impl(arr, low, pi - 1);
    quick_sort_impl(arr, pi + 1, high);
  }
}

// 冒泡排序
static void bubble_sort_impl(int arr[], int n)
{
  int i, j;
  for (i = 0; i < n - 1; i++)
  {
    for (j = 0; j < n - i - 1; j++)
    {
      if (arr[j] > arr[j + 1])
      {
        int temp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = temp;
      }
    }
  }
}

// 计数排序
static void counting_sort_impl(int arr[], int n)
{
  if (n == 0)
    return;

  int i;
  // 查找最大值和最小值
  int min_val = arr[0];
  int max_val = arr[0];
  for (i = 1; i < n; i++)
  {
    if (arr[i] < min_val)
      min_val = arr[i];
    if (arr[i] > max_val)
      max_val = arr[i];
  }

  // 计算范围
  int range = max_val - min_val + 1;

  // 分配计数数组
  int *count = (int *)calloc(range, sizeof(int));
  int *output = (int *)malloc(n * sizeof(int));

  if (count == NULL || output == NULL)
  {
    if (count)
      free(count);
    if (output)
      free(output);
    return;
  }

  // 计数
  for (i = 0; i < n; i++)
  {
    count[arr[i] - min_val]++;
  }

  // 累计计数
  for (i = 1; i < range; i++)
  {
    count[i] += count[i - 1];
  }

  // 构建输出数组
  for (i = n - 1; i >= 0; i--)
  {
    output[count[arr[i] - min_val] - 1] = arr[i];
    count[arr[i] - min_val]--;
  }

  // 复制回原数组
  for (i = 0; i < n; i++)
  {
    arr[i] = output[i];
  }

  // 释放内存
  free(count);
  free(output);
}

// 基数排序
static void radix_sort_impl(int arr[], int n)
{
  if (n == 0)
    return;

  int i;
  // 查找最小值和最大值
  int min_val = arr[0];
  int max_val = arr[0];
  for (i = 1; i < n; i++)
  {
    if (arr[i] < min_val)
      min_val = arr[i];
    if (arr[i] > max_val)
      max_val = arr[i];
  }

  // 处理负数:添加偏移量
  int offset = 0;
  if (min_val < 0)
  {
    offset = -min_val;
    for (i = 0; i < n; i++)
    {
      arr[i] += offset;
    }
    max_val += offset;
  }

  // 主排序循环
  int exp = 1;
  int *output = (int *)malloc(n * sizeof(int));
  if (output == NULL)
    return;

  while (max_val / exp > 0)
  {
    int count[10] = {0};
    int j;

    // 统计数字出现次数
    for (i = 0; i < n; i++)
    {
      j = (arr[i] / exp) % 10;
      count[j]++;
    }

    // 计算累计位置
    for (j = 1; j < 10; j++)
    {
      count[j] += count[j - 1];
    }

    // 构建输出数组(从后向前保持稳定性)
    for (i = n - 1; i >= 0; i--)
    {
      j = (arr[i] / exp) % 10;
      count[j]--;
      output[count[j]] = arr[i];
    }

    // 复制回原数组
    for (i = 0; i < n; i++)
    {
      arr[i] = output[i];
    }

    exp *= 10;
  }

  // 移除偏移量恢复原始值
  if (offset > 0)
  {
    for (i = 0; i < n; i++)
    {
      arr[i] -= offset;
    }
  }

  free(output);
}

// Python 接口函数
static PyObject *sort(PyObject *self, PyObject *args)
{
  PyObject *list;
  int sort_type;

  // 解析参数:列表和排序类型
  if (!PyArg_ParseTuple(args, "Oi", &list, &sort_type))
  {
    return NULL;
  }

  // 检查输入是否为列表
  if (!PyList_Check(list))
  {
    PyErr_SetString(PyExc_TypeError, "参数必须是列表");
    return NULL;
  }

  // 获取列表长度
  Py_ssize_t n = PyList_Size(list);

  // 分配整数数组
  int *arr = (int *)malloc(n * sizeof(int));
  if (arr == NULL)
  {
    PyErr_SetString(PyExc_MemoryError, "内存分配失败");
    return NULL;
  }

  // 将Python列表转换为C数组
  Py_ssize_t i;
  for (i = 0; i < n; i++)
  {
    PyObject *item = PyList_GetItem(list, i);
    if (!PyLong_Check(item))
    {
      free(arr);
      PyErr_SetString(PyExc_TypeError, "列表元素必须是整数");
      return NULL;
    }
    arr[i] = (int)PyLong_AsLong(item);
  }

  // 执行排序
  switch (sort_type)
  {
  case BUBBLE_SORT:
    bubble_sort_impl(arr, (int)n);
    break;
  case QUICK_SORT:
    quick_sort_impl(arr, 0, (int)n - 1);
    break;
  case COUNTING_SORT:
    counting_sort_impl(arr, (int)n);
    break;
  case RADIX_SORT:
    radix_sort_impl(arr, (int)n);
    break;
  default:
    free(arr);
    PyErr_SetString(PyExc_ValueError, "未知排序类型");
    return NULL;
  }

  // 构建返回列表
  PyObject *result = PyList_New(n);
  for (i = 0; i < n; i++)
  {
    PyList_SET_ITEM(result, i, PyLong_FromLong(arr[i]));
  }

  // 释放内存
  free(arr);
  return result;
}

// 方法定义
static PyMethodDef SortMethods[] = {
    {"sort", sort, METH_VARARGS, "执行排序算法"},
    {NULL, NULL, 0, NULL} // 哨兵
};

// 模块定义
static struct PyModuleDef sort_module = {
    PyModuleDef_HEAD_INIT,
    "sort_module",         // 模块名
    "C实现的排序算法模块", // 文档
    -1,                    // 模块状态大小
    SortMethods            // 方法表
};

// 模块初始化函数
PyMODINIT_FUNC PyInit_sort_module(void)
{
  return PyModule_Create(&sort_module);
}
  1. setup.py (编译脚本)
from setuptools import setup, Extension
import os

# 获取 Python 包含路径
python_include = os.path.join(os.path.dirname(os.__file__), 'include')

module = Extension(
    'sort_module',
    sources=['sort_module.c'],
    include_dirs=[python_include],
    extra_compile_args=['/O2', '/utf-8']  # 添加 /utf-8 选项
)

setup(
    name='sort_module',
    version='1.0',
    description='C实现的排序算法模块',
    ext_modules=[module]
)
  1. sort_module.pyi (类型提示文件)
from enum import IntEnum

class SortType(IntEnum):
    BUBBLE_SORT: int
    QUICK_SORT: int
    COUNTING_SORT: int
    RADIX_SORT: int

def sort(arr: list[int], sort_type: SortType) -> list[int]: ...
  1. 编译命令
python setup.py build_ext --inplace
  1. test_demo.py
# test_demo.py
from enum import IntEnum
from sort_module import sort

# 在 Python 中定义排序类型枚举
class SortType(IntEnum):
    BUBBLE_SORT = 0
    QUICK_SORT = 1
    COUNTING_SORT = 2
    RADIX_SORT = 3

# 生成测试数据
import numpy as np
import time

np.random.seed(42)
data = np.random.randint(0, 1000000, 100000).tolist()
print("原始数据长度:", len(data))
print("测试各种排序算法:")

sort_types = {
    SortType.BUBBLE_SORT: "冒泡排序",
    SortType.QUICK_SORT: "快速排序",
    SortType.COUNTING_SORT: "计数排序",
    SortType.RADIX_SORT: "基数排序"
}

for sort_type, name in sort_types.items():
    # 复制数据以避免修改原始数据
    test_data = data.copy()
    
    start = time.perf_counter()
    sorted_data = sort(test_data, sort_type.value)  # 使用 .value 获取整数值
    elapsed = time.perf_counter() - start
    
    # 验证排序结果
    assert sorted_data == sorted(data), f"{name}排序结果错误"
    
    print(f"{name}耗时: {elapsed:.6f}秒")

# 测试内置排序
start = time.perf_counter()
sorted(data)
builtin_time = time.perf_counter() - start
print(f"\nPython内置排序耗时: {builtin_time:.6f}秒")

# 测试边界情况
print("\n测试边界情况:")
test_cases = [
    ("空列表", []),
    ("单元素", [5]),
    ("负数", [-5, -3, -1, -2, -4]),
    ("混合", [-5, 0, 5, -3, 3]),
    ("重复", [5, 3, 5, 1, 3, 1]),
    ("有序", [1, 2, 3, 4, 5]),
    ("逆序", [5, 4, 3, 2, 1]),
]

for name, data in test_cases:
    print(f"\n测试用例: {name} - {data}")
    
    # 使用基数排序测试边界情况
    sorted_data = sort(data.copy(), SortType.RADIX_SORT.value)
    
    # 验证结果
    assert sorted_data == sorted(data), f"{name}测试失败"
    print(f"基数排序结果: {sorted_data}")
  1. 测试结果
原始数据长度: 100000
测试各种排序算法:
冒泡排序耗时: 8.441676秒
快速排序耗时: 0.006675秒
计数排序耗时: 0.004873秒
基数排序耗时: 0.004781秒

Python内置排序耗时: 0.012304秒       

测试边界情况:

测试用例: 空列表 - []
基数排序结果: []

测试用例: 单元素 - [5]
基数排序结果: [5]

测试用例: 负数 - [-5, -3, -1, -2, -4]
基数排序结果: [-5, -4, -3, -2, -1]   

测试用例: 混合 - [-5, 0, 5, -3, 3]   
基数排序结果: [-5, -3, 0, 3, 5]      

测试用例: 重复 - [5, 3, 5, 1, 3, 1]  
基数排序结果: [1, 1, 3, 3, 5, 5]

测试用例: 有序 - [1, 2, 3, 4, 5]
基数排序结果: [1, 2, 3, 4, 5]

测试用例: 逆序 - [5, 4, 3, 2, 1]
基数排序结果: [1, 2, 3, 4, 5]

点击下载示例代码:sort_demo.7z