彻底弄懂递归[心得](实例:归并排序)

心得:要弄懂递归,首先你得明白,堆栈的规则,函数调用的规则,本文涉及到GDB调试方法,如果你不会,参考这里http://www.wuzesheng.com/?p=1409.

其实GDB调试中,你就只需要懂一点点就OK,比如backtrace,GDB调试中简写为bt即可。

其次,你要不厌其烦的去单步调试,step单步,清清楚楚的看清楚每一步,你才能真正的弄懂递归原则,上课老师是不会给我们单步调试的,只是提大概的步骤,如果不亲自去调试,你确定你能彻底弄懂?不要怕麻烦,一步一步的按吧,仔细重复N遍,你就会领悟,本文用归并排序做例子,并在例子中给你一个理解的技巧,在注释中可见。利用树这个很好的递归理解工具,你会很轻松理解的,前提是你要理解树的深度优先搜索遍历(前、中、后序遍历)。


#include <iostream>

template <class T>
void Merge(T a[],T b[],int p,int q,int r) { //将排好序的两数组a[p:q]、a[q+1:r]合并
                                            //为一个有序数组到b[r]中。
    int i=p, j=q+1, k=p;                    //按由小到大排序
    while ((i <= q) && (j <= r)) {
        if (a[i] <= a[j])
            b[k++] = a[i++];
        else 
            b[k++] = a[j++];
    }
    if (i > q)
        for (int m=j; m <= r; m++)
            b[k++] = a[m];
    else 
        for (int m=i; m <= r; m++) {
            b[k++] = a[m];
        }
}

template <class T>
void Copy(T a[], T b[],int left,int right) {
    
    for (int i = left; i <= right; i++) {
        a[i] = b[i];
    }
    
    for (int i=left; i <= right; i++) {//用于观测每一次递归结果,非常清晰、方便。
        std::cout << a[i] << "  ";
    }
    std::cout << std::endl;
}

template <class T>
void MergeSort(T a[],int left,int right) { 
    if (left < right) { //至少有两个元素时
        int mid = (left + right)/2;
        MergeSort(a, left, mid);    //有没有发现,和树的后序遍历很像?
        MergeSort(a, mid+1, right); //对,就是树的后序遍历思想。
        T b[right+1];
        Merge(a,b,left,mid,right);//合并到数组b
        Copy(a,b,left,right); //复制回数组a
    }
}

int main (int argc, const char * argv[]) {
    
    int a[] = {1,3,6,2,3,8,4,7};
    int left = 0;
    int right = 7; //right = n-1
    MergeSort(a, left, right);
    for (int i=0; i <= right; i++) {
        std::cout << a[i] << "  ";
    }
    /*
     用于测试Merge()函数
     int a[] = {1,3,8,2,3,5};
     int b[6];
     Merge(a, b, 0, 2, 5);
     for (int i=0; i <= 5; i++)
     std::cout << b[i] << " ";
     */  
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值