合并排序算法的递归混淆

时间:2018-08-05 03:24:46

标签: mergesort

我对以下代码的输出感到困惑:

def msort3(x):
    print("splitting:",x)
    result = []
    if len(x) < 2:
        print("merging:",x)
        return x

    mid = int(len(x) / 2)
    y = msort3(x[:mid])
    print(y)
    z = msort3(x[mid:])  ## this will be run when x is 87
    print(z)
    i = 0
    j = 0
    while i < len(y) and j < len(z):
        if y[i] > z[j]:
            result.append(z[j])
            j += 1
        else:
            result.append(y[i])
            i += 1
    result += y[i:]
    result += z[j:]
    print("result is ", result)
    return result


if __name__ == '__main__':
     print("hi", msort3([17,87,6,22]))

其中一些输出是:

splitting: [17, 87, 6, 22]
splitting: [17, 87]
splitting: [17]
merging: [17]
[17]
splitting: [87]
merging: [87]
[87]
result is  [17, 87]
[17, 87]
splitting: [6, 22]

现在它怎么读[6,22]了?我认为到那时,当我们得到result = [17,87]时,递归调用已经完成。.请帮助,我非常困惑,已经在http://interactivepython.org/courselib/static/pythonds/SortSearch/TheMergeSort.html

处跟踪了代码

2 个答案:

答案 0 :(得分:0)

这正常工作。这是递归调用,其中缩进是深度:

[17, 87, 6, 22] <-- split
    [17, 87] <-- split
        [17]
        [87]
    [6, 22] <-- split
        [6]
        [22]

在下路,[17, 87]数组将在检查[6, 22]之前被完全检查并合并。在备份调用堆栈的过程中:

        [17]
        [87]
    [17, 87] <-- merge
        [6]
        [22]
    [6, 22] <-- merge
[6, 17, 22, 87] <-- merge

在这里,[17, 87]等待[6, 22]调用完全解决,剩下的[6, 17, 22, 87]合并在深度0处,是最终结果。

您的示例也可能会造成混淆,因为子数组[17, 87][6, 22]已经排序,因此唯一有影响的合并是[17, 87]和{{1之间的深度为0 }}。我建议尝试一些其他值,以查看是否有助于使其点击。

使用缩进技巧来帮助“查看”递归可以通过添加一个[6, 22]参数来完成(为了节省空间/便于阅读,我还简化了代码):

depth

输出:

def msort3(x, depth):
    result = []

    if len(x) < 2: 
        print(" " * depth + "single:",x)
        return x
    else:
        print(" " * depth + "splitting:",x)

    mid = len(x) // 2
    l = msort3(x[:mid], depth + 4)
    r = msort3(x[mid:], depth + 4)

    while l and r:
        if l[0] < r[0]:
            result.append(l.pop(0))
        else:
            result.append(r.pop(0))

    result += l + r
    print(" " * depth + "merged:", result)
    return result

print("\ndone:",msort3([17,87,6,22], 0))

这是repl

答案 1 :(得分:0)

因此,我尝试编写如下堆栈:

const http = require('http')

exports.handler = (event, context, callback) => {

    var auth = 'Basic ' + Buffer.from('JenkinsUserId:JenkinsAPIToken').toString('base64');

    var options = {
      host: 'example.com or ip address',
      path: '/jenkins/job/MyJenkinsJobName/job/RepoName/job/master/build?delay=0sec',
      port: '80',
      method: 'POST',
      headers: { 'Authorization': auth }
    };

   const req = http.request(options, (res) => {
        res.setEncoding('utf8');
        res.on('data', (chunk) => {
          // if you need the returned data modify here
        });
        res.on('end', () => {
          callback(null, 'Jenkins job triggered successfully')
        });
    });
    req.on('error', (e) => {
        console.log(e)
        callback(null, "An error occurred while triggering Jenkins job.");
    });
    req.end();
};

为此,We need to merge sort: [17,87,6,22] 为此,we need to merge sort [ 17,87]

我们这里有一个基本情况,还有we need to merge sort [17]

的合并方式

然后我们返回,并进行[17] is 17

的合并

我想在对这两个值进行排序之后,我仍然感到困惑,为什么又会发生变化,对于其他值又再次调用了mergesort的两个函数? 我假设合并[87]和17结束。执行将结束。

我已经写好了堆栈,我可以看到它仍然需要那种将整个列表合并的方法,但是每次调用函数时它如何保持left和right的值。我对执行感到困惑