【问题标题】:recursion in c stacks [closed]c堆栈中的递归[关闭]
【发布时间】:2013-08-27 13:15:35
【问题描述】:

这里是合并排序中的分区代码。我无法理解 recursion 在其中的工作原理!

合并排序分区

void partition(int arr[], int low, int high){
    int mid;
    if(low < high){
         mid = (low + high)/2;
         partition(arr, low, mid);
         partition(arr, mid + 1, high);
         mergeSort(arr, low, mid, high);
    }
}

实际上在许多递归问题中都搞砸了,并且无法理解系统堆栈在递归中是如何工作的...... 我是初学者..

【问题讨论】:

  • 您的方法签名表示QuickSort。我相信您已经将QuickSortMergeSort 混淆了。它们截然不同!
  • 从这段代码很难判断是什么问题。发布相关代码并阐明您所期望的未发生的情况。

标签: c algorithm sorting recursion


【解决方案1】:

我会尽量让递归函数更简单。举一个阶乘伪代码的小例子:

int fact(n)
{
  if(n==1 || n==0) return 1;
  else
  return (n*fact(n-1));
}

这将创建一个函数堆栈。假设我调用fact(3),这将产生如下堆栈:

fact(0)
fact(1)
fact(2)
fact(3)

每个函数被压入堆栈的地方。首先调用fact(3)fact(3) 致电 fact(2)。所以在通过之后--

堆栈建立:

                                               fact(0)
                                   fact(1)     fact(1)
                       fact(2)     fact(2)     fact(2)
empty --> fact(3) ---> fact(3) --> fact(3) --> fact(3)

现在函数捕获n=0 并返回1。现在功能开始弹出。

堆栈:

   fact(0) -----> (returns 1) = 1
                    fact(1) -----> (returns 1) * 1 (1's popped out)
                                     fact(2) -----> (returns 2) * 1 (1 is actually 1*1)
                                                      fact(3) -----> (returns 3) * (2 = 2*1*1)
                                                                                          ----->6

编辑:添加了 pop 功能。至于排序堆栈,请查看@P0W 的答案。

尝试举一个小例子并建立你的堆栈。然后转向复杂的。记住实践是关键。这就是递归函数作为堆栈工作的方式。

希望对您有所帮助。 :)

【讨论】:

  • 你能解释一下pop部分吗,并以同样的方式解释归并排序分区
  • 这是我在计算阶乘时解释递归的首选答案。很棒的答案!
【解决方案2】:

举个例子

数组arr ={ 5,2,4,7,1,3,2,6}; 8 个元素

                            1 2 3 4 5 6 7
                                  ^(partition+mergeSort)
                                  |  
                    +------------+ +---------------+
                    |                              |
                2 4 5 7                          1 2 3 6
                    ^   (partition+mergeSort)        ^ (partition+mergeSort)  
                    |                              |
                +--+ +---+                     +--+ +---+
                |        |                     |        |
               2  5     4  7                 1   3     2  6
                     ^ (partition+mergeSort)          ^  (partition+mergeSort) 
                     |                              | 
                +---+ +---+                    +---+ +---+
                |         |                    |         |
              5   2     4   7                1  3      2   6 
                 4 elements                      4 elements 

                          Initial Unsorted Array

从下往上,用

组成两个数组

arr[low...mid] 和 每次递归调用arr[mid+1...high],最后它们都被合并了。

只要low high

,分区和合并过程就会继续

这只是mergeSort 在此处工作的示例,您可以按照此示例的代码进行操作。

在这个未排序的数组上调用partition(arr, 0,7) 将有:

第一次通过mid =3 arr 使用

分为两部分

partion(arr,0,3)partion(arr,4,7)

每个分区再次分为两部分,即 0 到 3 分为 (0,1)(2,3) ,再进一步 (0,1)(1,1)(1,1) 被跳过,因为low &gt; high 最后两个元素与mergeSort 合并了

一组如此小的排序数组最终在随后的遍历中退出递归时被合并。

这里有点难解释,用文本格式,在纸上试一试,我相信你能弄明白,数组更小,比如 4 个元素。

【讨论】:

  • 你能说明一下递归是如何在其中工作的吗
  • thanx,你能告诉我哪些参数被传递给 mergeSort(arr, low, mid, high);每次以及如何
  • thanx,你能告诉我哪些参数被传递给 mergeSort(arr, low, mid, high);每次以及如何
  • @ayushnigam 已更新,但请在纸上试一试,这里有点难以解释。 fyi..mid=3 b'coz 的隐式类型转换
猜你喜欢
  • 2015-09-12
  • 2017-01-20
  • 2021-01-21
  • 2013-06-16
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2013-05-26
相关资源
最近更新 更多