通过归并排序算法(mergesort)理解递归在程序中的运行过程

递归的重要性不言而喻,它是很多算法实现的基础,比如含有分治思想的算法(归并排序,二分查找),有关遍历二叉树的算法,或者求解数学递推式的算法(斐波那契数列,n的阶乘),回溯法,动态规划等等, 一提到递归总有点发蒙,理论上比较好理解,但是一遇到复杂一点的递归算法,在大脑中很难想象递归在计算机中是怎么实现的。跟着一步步debug才终于搞明白,所以在这里先把过程给记录下来。
归并排序算法:就是运用分治的思想,把排序的过程变为先把数组分成左右两个部分,分别排序,再将排好序的两个数组合并成一个有序数组。
代码:

void Merge(vector<int>& inputArray, int p, int q, int r)
    {
        int i = p;
        int j = q + 1;
        vector<int> temp;
        while (i <= q && j <= r)
        {
            if (inputArray[i] <= inputArray[j]) {
                temp.push_back(inputArray[i]);
                i++;
            }
            else
            {
                temp.push_back(inputArray[j]);
                j++;
            }
        }

        int start = i;
        int end = q;
        if (j <= r)
        {
            start = j;
            end = r;
        }

        for (int jj = start; jj <= end; jj++)
        {
            temp.push_back(inputArray[jj]);
        }
           

        for (int ii = 0; ii < temp.size(); ii++)
        {
            inputArray[p+ii] = temp[ii];
        }
    }

    void Merge_sort_c(vector<int>& inputArray, int p, int r)
    {
        if (p >= r) return;
        int q = (p + r) / 2;
        Merge_sort_c(inputArray, p, q);  //左边排序 #1
        Merge_sort_c(inputArray, q + 1, r);//右边排序 #2
        Merge(inputArray, p, q, r);//合并两个有序数组

    }

    vector<int> MergeSort(vector<int>& inputArray)
    {
        int n = inputArray.size();
        Merge_sort_c(inputArray, 0, n-1);
        return inputArray;
        
    }
int main()
{
    vector<int> input = { 4,5,6,3,2,1 };
    vector<int> output = MergeSort(input);
    for (int i = 0; i < output.size(); i++)
    {
        cout << output[i] << endl;
    }

}

重点分析一下代码中 Merge_sort_c这个递归函数,首先是终止条件p>=r ,递归必须要有终止条件,否则就会陷入循环最终导致栈溢出。为啥会栈溢出?递归调用在底层其实是对线程栈的压栈和出栈操作,每调用一次都会压栈一次,并记录相关的局部变量信息,线程栈的内存是非常有限的,而递归调用如果是无限的,那么很快就会消耗完所有的内存资源,最终导致内存溢出。
接下来是两个调用了Merge_sort_c 函数本身也就是递归调用,将这两个递归调用分别编号#1和#2.在本例中,待排序的数组里面有6个元素(下标0-5), 那么他们是怎么被压栈又出栈的呢?如下图所示:

通过归并排序算法(mergesort)理解递归在程序中的运行过程_第1张图片

通过归并排序算法(mergesort)理解递归在程序中的运行过程_第2张图片merge 的过程

你可能感兴趣的:(数据结构与算法)