【问题标题】:How implement a recursive version of this function如何实现此函数的递归版本
【发布时间】:2017-11-13 03:41:06
【问题描述】:

我需要实现这个函数的递归版本:

static void peneira (int m, int v[]) {
    int f=2, t;
    while(f<=m){
        count_Iteracoes_HeapSort++;
        if(f<m && v[f] < v[f+1])++f;
        if(v[f/2] >= v[f]) break;
        t = v[f/2]; v[f/2] = v[f]; v[f] = t;
        f *= 2;
    }

}

我正在做这样的事情:

static void peneiraRec(int m,int v[]){
    count_Iteracoes_HeapSort++;
    int f=2,t;
    if(m<=1) {
        return;
    }
    while(f<=m) {
        peneiraRec(m - 1, v);
        if (f < m && v[f] < v[f + 1]) ++f;
        if (v[f / 2] >= v[f]) break;
        t = v[f / 2];v[f / 2] = v[f];v[f] = t;
        f *= 2;
    }
}

但这不起作用。谁能帮帮我?

该函数是堆排序的辅助函数。我将发布所有代码

 static void 
constroiHeap (int m, int v[])
{
   int k; 
   for (k = 1; k < m; ++k) {                   
      // v[1..k] é um heap
      int f = k+1;
      while (f > 1 && v[f/2] < v[f]) {  // 5
         troca (v[f/2], v[f]);          // 6
         f /= 2;                        // 7
      }
   }
}

static void peneira (int m, int v[]) {
    int f=2, t;
    while(f<=m){
        count_Iteracoes_HeapSort++;
        if(f<m && v[f] < v[f+1])++f;
        if(v[f/2] >= v[f]) break;
        t = v[f/2]; v[f/2] = v[f]; v[f] = t;
        f *= 2;
    }

}

void
heapsort (int n, int v[])
{
   int m;
   constroiHeap (n, v);
   for (m = n; m >= 2; --m) {
      troca (v[1], v[m]);
      peneira (m-1, v);
   }
}
int main{
  int v0[6] = {0,63726,2323,0,32,236723};
  heapsort_rec(5, v0);
}

输出:v0 = 0,32,2323,63726,236723

基本上,我需要我的输入是一个排序的数组,输出应该是有序的数组。

我需要递归实现这个 peneira 函数

【问题讨论】:

  • 你能提供一些关于这个函数的用途的信息吗?
  • 是作业还是类似的?
  • 显示上下文,显示函数应该如何使用,定义目的,提供示例输入,即创建一个minimal reproducible example,使用tour 为您的个人资料做一些漂亮的装饰。
  • 旁白:当f 可以等于m 时,v[f+1] 看起来很可疑。

标签: c recursion data-structures heapsort


【解决方案1】:

我在cgss回答后做了这样的事情

void peneiraRec(int m,int v[], int f){
    count_Iteracoes_HeapSort++;
    int t;
    if(f>m){
        return;
    }
    if(f<m && v[f] < v[f+1])++f;
    if(v[f/2] >= v[f]) return;
    t = v[f/2]; v[f/2] = v[f]; v[f] = t;
    peneiraRec(m,v,f*2);
}

void heapsort_rec(int n, int v[]){
    int m;
    constroiHeap (n, v);
    for (m = n; m >= 2; --m) {
        count_Iteracoes_HeapSort;
        int t=v[1]; v[1]=v[m]; v[m]=t;
        peneiraRec (m-1, v,2);
    }
}

而且它有效,我想我做到了。我没有看到我的脸,只有f 没有改变m,真的谢谢你们,对不起我的愚蠢解释,我是stackoverflow 的新手。

【讨论】:

  • 错了。当第一个递归步骤返回时,整个算法就完成了,但 while 循环将继续迭代。您可能很幸运,您的循环体是幂等的,因此后续迭代无事可做。但是对于非幂等操作,这会给出错误的结果。
  • 这和我现在的回答一样(除了参数的顺序),所以我会说它是对的!但是,我之前的评论现在对这个新代码毫无意义。
  • 谢谢哥们!!您的第一条评论是在我编辑答案时上传的,哈哈,顺便说一句谢谢!
【解决方案2】:

任何循环都可以通过将循环体变成一个以循环变量作为参数的函数(除了循环内使用的变量)来实现递归。该函数首先测试循环变量以查看是否已达到边界,如果已达到则返回。否则,它执行一次循环迭代,然后使用循环变量的新值调用自身。通常,您将需要两个功能;递归步骤函数,以及另一个使用循环变量的初始值调用递归步骤的函数。

static void peneira_rec (int f, int m, int v[]) {
    int t;
    if(f > m) return; // exit loop

    count_Iteracoes_HeapSort++;
    if(f<m && v[f] < v[f+1])++f;
    if(v[f/2] >= v[f]) return; // exit loop
    t = v[f/2]; v[f/2] = v[f]; v[f] = t;
    peneira_rec(f*2, m, v); // loop again
}

static void peneira (int m, int v[]) {
    peneira_rec(2, m, v); // start the loop
}

【讨论】:

  • 我做了一段时间的功能,以防止创建另一个功能。你觉得这种方式更好吗?
  • 使函数递归的重点是替换while循环
  • 我现在明白了,我已经删除了 while 循环,它工作得很好
  • 你能点击正确答案旁边的复选标记吗?
【解决方案3】:

首先,你为什么调用 peneiraRec 并以 m-1 作为它的第一个参数。在非递归实现中 m 不会改变,只有 f 会改变。其次,每次调用函数时 f 都设置为 2 并且您不希望这样。您希望 f 是其先前值的 2 倍。第三为什么使用头递归而不是尾递归。我的建议是将 peneiraRec 的定义更改为 peneiraRec (int m, int v[], int f)。第一次需要使用 f = 2 aw 调用它的第三个参数,然后递归调用它作为 peneiraRec (m ,v ,2*f)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2021-06-27
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多