使用 Cython 高效实现 对整型(int)列表(List)的 归并排序(MergeSort)

14 篇文章 0 订阅

考虑到由于python执行效率不高,使用纯py实现MergeSort归并排序并没有太大价值,因此选择 Cython(语法类似Python) 。它可以把代码编译成调用了 Python 源码的 C/C++ 代码,从而提高执行效率

由于代码最终被编译为py库,所以需要先根据官方说明文档编写以下配置代码

# cython: language_level=3
# merge_sort_setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("merge_sort.pyx")
)

再在同目录以cython语法编写排序算法

# cython: language_level=3
# merge_sort.pyx
cimport cython
from cpython.mem cimport PyMem_Malloc, PyMem_Free
from libc.string cimport memcpy

@cython.boundscheck(False)
@cython.wraparound(False)

def sort(list l):    #从小到大排列list
    cdef int length = len(l), cnt = 0
    cdef int* clist = <int*>PyMem_Malloc(length * sizeof(int))
    for i in l:
        if isinstance(i, int):
            clist[cnt] = i
            cnt += 1
        else: return []    #如果不是纯数字则返回空list
    return getList(_csort(clist, length), length)

cdef int* _csort(int* l, int length):
    cdef int half, a, b, c, *list1, *list2, *listRet
    
    if length > 2:
        half = int(length/2)
        list1 = _csort(cutList(l,0,half), half)
        list2 = _csort(cutList(l,half,length - half), length - half)
        a, b, c = 0, 0 ,0
        PyMem_Free(l)
        listRet = <int*>PyMem_Malloc(length * sizeof(int))
        while a < half and b < length - half and c < length:
            if list1[a] <= list2[b]:
                listRet[c] = list1[a]
                a += 1
            else:
                listRet[c] = list2[b]
                b += 1
            c += 1
        while a < half:
            listRet[c] = list1[a]
            a += 1
            c += 1
        while b < length - half:
            listRet[c] = list2[b]
            b += 1
            c += 1
        PyMem_Free(list1)
        PyMem_Free(list2)
        return listRet
    elif length == 2:
        if l[0] > l[1]: l[0], l[1] = l[1], l[0]
        return l
    else: return l

cdef inline int* cutList(int* res, int start, int length):
    cdef int* des = <int*>PyMem_Malloc(length * sizeof(int))
    memcpy(des, res + start, length * sizeof(int))
    return des

cdef inline getList(int* res, int length):
    cdef int cnt = 0
    re = []
    while cnt < length:
        re.append(res[cnt])
        cnt += 1
    PyMem_Free(res)
    return re

接下来使用如下命令即可生成库文件

python3 merge_sort_setup.py build_ext --inplace

import进行测试

$ python3
Python 3.8.5 (default, Jul 21 2020, 10:42:08) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import merge_sort
>>> merge_sort.sort([11,10,9,8,7,6,5,4,3,2,1])
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> merge_sort.sort([9,8,7,6,5,4,3,2,1])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> merge_sort.sort([9,8,7,6,5,4,3,2,1,3,234,23524,23433,5789,432,676,234123,2,56856,213124])
[1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 234, 432, 676, 5789, 23433, 23524, 56856, 213124, 234123]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值