计算Merge_Sort算法的工作

时间:2017-11-04 17:45:03

标签: python algorithm count global-variables mergesort

全部,我想通过使用合并排序算法来计算数组的排序距离。我可以使用Merge Sort来排列数组,但我无法计算在此过程中需要多少次反转。

例如,当输入[9,4,8​​,3]时,我想获得输出[3,4,8,9]和4次反转。反演的定义是:如果B中的b,c中的c并且我们具有b> c,则需要反演(B,C的顺序)。首先,我将得到两个部分([4,9],1)和([3,8],1),它们分别表示一个反演。然后,当他们再次合并时,还有另外两个反转:选择3而不是4,选择8而不是9。

我的主要问题可能与算法本身无关。它是关于如何保持我的变量之一在函数的函数循环中进化。 (我在Merge_Sort函数中使用了Merge_Sort函数)

def Merge_Sort(a):
    n = len(a)
    if n==1:
        if not 'total_rev' in vars():            
            total_rev = 0
        else:
            total_rev += rev_ind
    return a , total_rev
    else:
        m = math.floor(n/2)
        b , rev_ind_b = Merge_Sort(a[:m])
        if not 'total_rev' in vars():
            total_rev = 0
        else:
            total_rev += rev_ind_b
        c , rev_ind_c = Merge_Sort(a[m:])
        if not 'total_rev' in vars():
            total_rev = 0
        else:
            total_rev += rev_ind_c      
        a_sort , rev_ind = Merge(b,c)
        if not 'total_rev' in vars():
            total_rev = 0
            total_rev += rev_ind
        else :
            total_rev += rev_ind
        return a_sort , total_rev

def Merge(b,c):
    p = len(b)
    q = len(c)
    d = []
    reverse_ind = 0
    while len(b)!=0 or len(c)!=0 :
        if (len(b)*len(c) != 0) :
            b0 = b[0]
            c0 = c[0]
            if b0 <= c0 :
                d.append(b0)
                b.remove(b[0])
            else :
                reverse_ind += 1
                d.append(c0)
                c.remove(c[0])
        else :
            d.extend(b)
            b=[]
            d.extend(c)
            c=[]
    return d,reverse_ind

合并功能可以很好地工作。唯一的问题是我无法保留变量&#34; total_inv&#34;按我的意愿更新。我试着定义&#34; total_inv&#34;无论什么时候没有定义。不确定它是否是一个好方法,因为它使我的代码混乱。我也尝试使用全局变量,但它不能很好地工作。谢谢!

1 个答案:

答案 0 :(得分:1)

比这简单:

  • 当处于最深的递归级别(n==1)时,只需为交换次数返回0。逻辑是你应该在递归级别返回列表的交换次数,因为它是,而不考虑更大的列表可能是什么。因此,当n==1列表中有一个值时,显然不需要交换。
  • 在其他情况下,只需添加从递归调用中获得的计数。这样,当冒泡返回递归树时,它们会增加。

以下是Merge_Sort的修改代码:

def Merge_Sort(a):
    n = len(a)
    if n==1:
        return a, 0 # at deepest recursion always return 0 for the number of swaps
    else:
        m = n//2 # use integer division; you don't need `math.floor`
        b , rev_ind_b = Merge_Sort(a[:m])
        c , rev_ind_c = Merge_Sort(a[m:])
        a_sort , rev_ind = Merge(b,c)
        return a_sort , rev_ind_b + rev_ind_c + rev_ind # add the numbers