【问题标题】:Python 'pointer arithmetic' - QuicksortPython '指针算法' - 快速排序
【发布时间】:2014-06-18 03:49:46
【问题描述】:

在惯用的 C 方式中,可以使用两个参数以一种简单的方式实现快速排序:

void quicksort(int inputArray[], int numelems);

我们可以通过指针运算安全地为以后的细分(即通常所说的分区)使用两个参数:

//later on in our quicksort routine...
quicksort(inputArray+last+1, numelems-last-1);

事实上,我之前什至在 SO 上问过这个问题,因为当时我没有受过指针算术训练:见 Passing an array to a function with an odd format - “v+last+1”

基本上,是否可以在 python 中复制相同的行为,如果可以,如何复制?我注意到列表可以用方括号内的冒号(切片运算符)进行细分,但是切片运算符从那时起不再传递列表;也就是说,在这两种情况下,第一个元素(第 0 个索引)仍然相同。

【问题讨论】:

    标签: python c arrays list pointers


    【解决方案1】:

    如您所知,Python 的切片语法会生成一个副本,因此为了在适当的位置操作列表的子部分(不是“数组”,在 Python 中),您需要同时传递列表和开始-讨论部分的索引和大小(或结束索引),就像在 C 中一样。递归函数的签名类似于:

    def quicksort( inputList, numElems, startIndex = 0 ):
    

    递归调用类似于:

    quicksort( inputList, numElems-last-1, last+1 )
    

    在整个函数中,您可以将startIndex 添加到您要进行的任何列表访问中。

    【讨论】:

    • 啊,是的,谢谢你提醒我;我已经在我的问题中反映了更新(列表到数组)。那么,最终没有办法用二元参数列表实现类似的功能吗?
    • 二元参数列表?你真的关心函数的arity吗?我的意思是,您可以定义一个包含列表和边界信息的类,并使用其中之一使函数调用一元化,或者您可以定义一个具有 C 数组样式语义的类,并在其中工作。跨度>
    • 纯粹出于好奇和探索。事实上,我什至不应该将 C 方法称为“功能性”,因为它比它更聪明,而且对于代码的读者来说肯定并不总是那么清晰(就像我最初关于 v+last+1 的帖子一样)。再次感谢!
    【解决方案2】:

    我想如果您想做类似的事情,您可以执行以下操作:

    # list we want to mutate
    sort_list = [1,2,3,4,5,6,7,8,9,0]
    
    #wrapper just so everything looks pretty, process could go here if we wanted
    def wrapper(a, numlems):
        cut = len(a) - numlems
        # overwrites a part of the list with another one
        a[cut:] = process(a[cut:])
    
    # processing of the slice
    def process(a):
        # just to show it works
        a[1] = 15
        return a
    
    wrapper(sort_list, 2)
    print(sort_list)
    
    wrapper(sort_list, 4)
    print(sort_list)
    
    wrapper(sort_list, 6)
    print(sort_list)
    

    这在 python 中可能被认为是非常邪恶的,我不会真的推荐它,但它确实模拟了你想要的功能。


    对于python,你只需要:

    def quicksort(inputList, startIndex):
    

    然后创建和连接切片就可以正常工作,而无需类似指针的功能。

    【讨论】:

    • 您无需直接致电__setslice__a[cut:] = process(a[cut:])
    • 哦,太好了,我错误地认为切片总是会创建副本,谢谢。
    猜你喜欢
    • 2017-02-27
    • 1970-01-01
    • 2020-06-05
    • 2021-08-01
    • 2020-09-11
    • 1970-01-01
    • 2016-11-24
    • 2018-05-17
    • 1970-01-01
    相关资源
    最近更新 更多