为什么我的合并排序算法不起作用?

时间:2019-07-02 09:26:39

标签: python-3.x algorithm sorting mergesort

我正在Python中实现合并排序算法。以前,我已经在C语言中实现了相同的算法,但是在C语言中可以正常工作,但是当我在Python中实现时,它会输出未排序的数组。

我已经重新检查了算法和代码,但据我所知,代码似乎是正确的。

我认为这个问题与Python中变量的范围有关,但是我不知道如何解决它。

from random import shuffle
# Function to merge the arrays
def merge(a,beg,mid,end):
    i = beg
    j = mid+1
    temp = []
    while(i<=mid and j<=end):
        if(a[i]<a[j]):
            temp.append(a[i])
            i += 1
        else:
            temp.append(a[j])
            j += 1
    if(i>mid):
        while(j<=end):
            temp.append(a[j])
            j += 1
    elif(j>end):
        while(i<=mid):
            temp.append(a[i])
            i += 1

    return temp



# Function to divide the arrays recursively
def merge_sort(a,beg,end):
    if(beg<end):
        mid = int((beg+end)/2)
        merge_sort(a,beg,mid)
        merge_sort(a,mid+1,end)
        a = merge(a,beg,mid,end)

    return a

a = [i for i in range(10)]
shuffle(a)
n = len(a)
a = merge_sort(a, 0, n-1)
print(a)

2 个答案:

答案 0 :(得分:1)

要使其正常工作,您需要稍微更改merge_sort声明:

def merge_sort(a,beg,end):
    if(beg<end):
        mid = int((beg+end)/2)
        merge_sort(a,beg,mid)
        merge_sort(a,mid+1,end)
        a[beg:end+1] = merge(a,beg,mid,end)  # < this line changed
    return a

为什么:

temp的构造不得超过end-beg + 1,但a是初始的完整数组,如果您设法替换所有数组,则会很快感到厌烦。因此,我们采用a的“切片”,并替换该切片中的值。

为什么不呢?

幸运的是,由于Python的内部功能,您的a并没有被替换,这很难解释,但我会尽力的。 Python中的每个变量都是一个引用。 a是对变量a[i]的引用,而变量a则是对内存中的常量的引用。 当您将a传递给函数时,它将产生一个新的局部变量a=***,该变量指向相同的变量列表。这意味着当您将其重新分配为a时,它只会更改return指向的位置。您只能通过“切片”或通过a语句将更改传递到外部

为什么“切片”起作用:

切片很棘手。正如我所说的a[i]指向其他变量的数组(基本上是a),它们依次引用了内存中的常量数据,并且当您重新分配切片时,它将逐个切片地遍历以及这些单个变量指向的位置的更改,但是当NSMutableDictionary *audioObjectInfo = [[NSMutableDictionary alloc] init]; audioObjectInfo[MPMediaItemPropertyTitle] = @"Title"; audioObjectInfo[MPMediaItemPropertyArtist] = @"User"; audioObjectInfo[MPMediaItemPropertyAlbumTitle] = @"Collection"; [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:audioObjectInfo]; 的内部和外部仍然指向相同的旧元素时,更改就会经历。

希望有道理。

答案 1 :(得分:0)

您不使用递归合并的结果,因此您实质上报告了两个未排序的两半的合并结果。