如何实现此函数的递归版本

时间:2017-06-11 16:45:39

标签: c recursion data-structures heapsort

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

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

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

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

3 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

在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的新手。