在没有全局Python的情况下计算比较快速排序

时间:2014-11-05 09:08:59

标签: python python-3.x global-variables quicksort

我有一个快速排序和计数比较的代码,完美运行。但是每次我调用该函数时,计数都会一次又一次地加起来。有什么方法可以避免这种情况吗?

count = 0
def quicksort(A, left = None, right =None):
    global count
    if left is None:
        left = 0
    if right is None:
        right = len(A)
    if left >= right:
        return
    p =A[left]

    i = left +1
    for j in range(left+1,right):
        if A[j] < p:
            A[i] , A[j] = A[j], A[i]
            i = i + 1
    A[left] , A[i-1] = A[i-1], A[left]
    quicksort(A,left,i-1)
    count += i-1-left
    quicksort(A,i,right)
    count += right-i-1

    return A,count+len(A)

1 个答案:

答案 0 :(得分:0)

为了使其适用于全局count,您需要在递归的第一级重置它。一种方法是将您的实现移动到一个单独的函数_quicksort递归调用自己,并在调用之前重置计数器:

def quicksort(A):
    global count
    count = 0
    return _quicksort(A)

def _quicksort(A, left=None, right=None):
    global count
    ...
    _quicksort(A,left,i-1)
    ...

此外,这简化了您的主要功能签名,因为quicksort最终用户并不需要了解leftright

现在,最好不要使用全局变量,因为这是一种不好的做法。然后,您需要以某种方式将上下文传递给_quicksort函数,以便知道要处理哪个计数器。所以你需要传递一些东西作为参数:

def _quicksort(context, A, left=None, right=None):
    ...
    _quicksort(context, ...)

例如,此context可以是{'count': 0}之类的字典,您可以将其作为context['count']进行访问,也可以是使用context.count的对象。请注意,在这种情况下,这非常接近类,其中上下文是对象本身,_quicksort将是类方法:

class _Quicksort(object):
    count = 0
    def _quicksort(self, A, left=None, right=None):
        ...
        self._quicksort(A, ...)
        self.count += ...

最后,在递归函数中处理上下文的另一种常用方法是“按值”传递和返回变量,例如:

def _quicksort(count, other_context, A, left=None, right=None):
    ...
    count1, other_context1 = _quicksort(count, other_context, A, left, right)
    ...
    return count + count1, other_context

但是你最终会得到一个杂乱的方法签名,并且必须弄清楚count在这种情况下的含义以及如何获得相同的结果(这是一个很好的练习!)。