【问题标题】:merge sort with recurrsion递归合并排序
【发布时间】:2019-01-22 02:44:51
【问题描述】:
    /*
This code is Written by Shankhadeep Dey
(15th Aug 2018)
*/
#include<iostream>
using namespace std;
void merge(int a[],int p,int q,int r)
{
    int n1,n2,j,i,k;
    n1= q-p+1;
    n2= r-q;
    int L[n1],R[n2];
    for (i = 0; i < n1-1; ++i)
        L[i]=a[p+i-1];
    for (j = 0; j < n2-1; ++j)
        R[j]=a[q+j];
    L[n1]=1e9;
    R[n2]=1e9;
    i=0;
    j=0;
    for (k = p; k < r; ++k)
    {
        if (L[i]<=R[j])
        {
            a[k]=L[i];
            i++;
        }
        else
        {
            a[k]=R[j];
            j++;
        }
    }
    while (i < n1)
    {
        a[k] = L[i];
        i++;
        k++;
    }

    /* Copy the remaining elements of R[], if there
       are any */
    while (j < n2)
    {
        a[k] = R[j];
        j++;
        k++;
    }
}
void mergeSort(int a[],int p,int r)
{
    int q;
    if (p<r)
    {
        q= (p+r)/2;
        mergeSort(a,p,q);
        mergeSort(a,q+1,r);
        merge(a,p,q,r);
    }
}
int main()
{   int w[4]={4,3,21,5};
    mergeSort(w,0,3);
    for (int i = 0; i < 4; ++i)
    {
        cout<<w[i]<<" ";
    }
    cout<<endl;
}

谁能告诉我为什么这种排序不起作用? 我从“算法简介”一书中尝试了这个算法,但我不太确定为什么这段代码没有运行。我尝试在线搜索合并排序并找到很多东西,但我确实想知道我的代码有什么问题。 输出为:-0 1000000000 1 1000000000(这不是正确的答案)。
这是我收到的警告

mergeSort.cpp: In function ‘void merge(int*, int, int, int)’:
mergeSort.cpp:12:10: warning: ISO C++ forbids variable length array ‘L’ [-Wvla]
  int L[n1],R[n2];
          ^
mergeSort.cpp:12:16: warning: ISO C++ forbids variable length array ‘R’ [-Wvla]
  int L[n1],R[n2];

【问题讨论】:

  • 定义“不工作”。没有输出?输出不正确?崩溃?不编译?
  • 您是否尝试过打开编译器警告并阅读它们?这些应该可以揭示问题。
  • 从一开始,这就是无效的 C++。提高编译器的严格性(在 clang/gcc 上使用 -pedantic)。
  • edit你的问题告诉我们你做了什么样的调试。我希望您已经在 Valgrind 或类似的检查器中运行了您的minimal reproducible example,并使用诸如 GDB 之类的调试器进行了调查。确保您也启用了全套编译器警告。这些工具告诉了你什么,它们缺少什么信息?并阅读 Eric Lippert 的 How to debug small programs
  • int L[n1],R[n2]; 这样的东西不是有效的C++,因为C++ doesn't have variable length arrays。由于 GCC 非标准扩展,这样的代码有时可以编译。你应该使你的数组​​固定大小或使用std::vector

标签: c++ sorting recursion merge mergesort


【解决方案1】:

您的合并逻辑存在问题。想想当您想要合并数组中的前两个元素时会发生什么。在这种情况下,p=0、q=0 和 r=1。在这种情况下n1=0,并且以下循环永远不会执行:

for (i = 0; i < n1-1; ++i)
    L[i]=a[p+i-1];

与下一个循环相同。更糟糕的是,如果您通过将n1-1 更改为n1 来修复它,那么在第一次迭代中,p+i-1 将是-1,这会导致更多问题。

如果你想通过比较一个可行的解决方案来作弊,我相信How to implement merge sort from "The Introduction to Algorithms" by Cormen and Co有一个

更一般地说,我建议使用逐行调试器(gdb 或使用 Eclipse 之类的 IDE)将允许您逐行执行代码,检查何时执行什么以及每个变量的值是什么步。这使得诊断这样的错误变得更加容易。


(注意:此问题已在问题编辑中修复)。

这几行有问题:

for (int i = 0; i < n2-1; ++i)
    R[j]=a[q+j];

使用ji,但不能同时使用。目前您使用的是未初始化的值j


顺便说一句,您声明了变量ij 两次(一次在函数顶部附近,再次在for 循环中)。这不会阻止程序运行,但是在不同的范围内拥有两个同名的变量并不是很好的做法,因为它可能会导致混淆。

另外,在这一行:

q= (int)(p+r)/2;

(int) 部分没有任何作用,可能会误导读者。 pr 已经是整数,因此编译器使用整数除法产生整数结果。

【讨论】:

  • 我已经更新了我的答案,并在顶部添加了一些建议
猜你喜欢
  • 1970-01-01
  • 2021-11-06
  • 2020-03-04
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多