简体   繁体   English

合并排序函数上的递归令人困惑

[英]Recursion on a merge sort function is confusing

I understand the basic principle of a recursion, and it is not confusing at all when dealing with simple things such as calculating a number's factorial, which is the most basic usage of a recursion. 我了解递归的基本原理,在处理简单的事情(例如计算数字的阶乘)时,它一点也不混淆,这是递归的最基本用法。 However, when you start using Recursion in more complicated environments, it starts getting really really confusing for me. 但是,当您在更复杂的环境中开始使用递归时,它对我来说真的很令人困惑。

In my case, I wanted to create a function which used the "merge sort" way to sort the items in a list, using a recursion. 就我而言,我想创建一个函数,该函数使用“合并排序”方式通过递归对列表中的项目进行排序。 So i got to work and this is what i came up with at my first attempt (not really I had to fix some typos): 所以我开始工作,这是我第一次尝试时想到的(不是我真的必须解决一些错字):

def merge_sort(ls):
  size = len(ls)
  if size <= 1:
    return ls
  left = merge_sort(ls[:size/2])
  right = merge_sort(ls[size/2:])
  return merge(left, right)

def merge(left, right):
  ls = []
  ln1 = len(left)
  ln2 = len(right)
  length = ln1 + ln2
  while length > 0:
    if not left:
      ls.append(right.pop(0))
      length -= 1
    elif not right:
      ls.append(left.pop(0))
      length -= 1
    else:
      if left[0] < right[0]:
        ls.append(left.pop(0))
        length -= 1
      elif right[0] < left[0]:
        ls.append(right.pop(0))
        length -= 1
  return ls

print merge_sort([8,5,4,6,1])

I clicked run and it worked, but I don't understand why it works. 我单击运行,它起作用了,但是我不明白为什么它起作用。 Yes, I created a piece of code which does what was intended to do but I don't understand why. 是的,我创建了一段代码,该代码可以完成预期的工作,但我不明白为什么。

So "merge_sort" splits the list into two pieces until there is a simple list with a single item. 因此, “ merge_sort”将列表分为两部分,直到有一个包含单个项目的简单列表为止。 It does this using recursion, and when we get a simple list with a single item it assigns it to a new list, which is left or right . 它使用递归进行此操作,当我们获得一个包含单个项目的简单列表时,它将其分配给一个新列表,即leftright Then i use these 2 new lists in the "merge" function to sort them and merge them together in the right way. 然后,我在“合并”功能中使用这2个新列表对它们进行排序,并以正确的方式将它们合并在一起。 So far so good, but what I was expecting when I hit "execute" was for the code to stop here at the first 2 items and print a small list with 2 sorted items. 到目前为止,一切都很好,但是当我点击“执行”时,我期望代码在前两个项目处停止并打印一个包含2个已排序项目的小列表。 However "merge_sort" keeps going. 但是“ merge_sort”一直在继续。 Even though i believe it should ends after executing: 即使我相信它应该在执行后结束:

return merge(left, right)

Now this is my question. 现在这是我的问题。 Why does it return back to the start of "merge_sort" and how does it save the old values without screwing up the new sorted "small list" generated by "merge" ? 为什么它返回“ merge_sort”的开头,又如何保存旧值而又不弄乱 “ merge”生成的新排序的“小列表呢? I hope my question makes sense to you. 希望我的问题对您有意义。

Thank you for the help guys! 谢谢您的帮助!

the answer to this is a pretty broad one. 答案很广泛。 to fully understand this, you need to understand how a stackbuildup works with recursion and how the pointers in said buildup work. 为了完全理解这一点,您需要了解堆栈构建如何与递归一起工作以及所述构建中的指针如何工作。

This is called recursively because the list needs to be broken down by dividing it in half until it is at the smallest possible unit (remainder of 1 or 0) Once this is done, the stack buildup will use its predefined pointers to traceback all of the previous call instances. 递归调用此方法是因为需要通过将列表分成两半来分解,直到达到最小可能的单位(剩余的1或0)。一旦完成,堆栈构建将使用其预定义的指针来追溯所有先前的通话实例。

this is an indepth programming languages concept. 这是一个深入的编程语言概念。

for more information on stack buildups and call backs reference here. 有关堆栈构建和回调参考的更多信息,请参见此处。 https://en.wikipedia.org/wiki/Call_stack https://en.wikipedia.org/wiki/Call_stack

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM