【问题标题】:why the below merge sort code doesnt work?为什么下面的合并排序代码不起作用?
【发布时间】:2016-02-06 16:34:36
【问题描述】:

下面的代码应该改变什么?它显示以下错误

错误:ld.so:来自 LD_PRELOAD 的对象“/home/bot/funcs.so”无法预加载(无法打开共享对象文件):已忽略。

`/home/bot/dcb7b4b8f54571a4467c2113b7856878' 中的错误:free():下一个大小无效(快速):0x0000000000c350b0

      #include <iostream>

      using namespace std;

      int merge(int *left,int nl,int *right,int nr,int *a)
      {

         int i=0,j=0,k=0;
         while(i<nl && j<nr)
         {
            if(left[i]<right[j])
            {
             a[k]=left[i];
             i++;
            }
            else
            {
             a[k]=right[j];
             j++;
             }
            k++;
           }
        while(i<nl)
        {
         a[k]=left[i];
          i++;
        }
       while(j<nr)
       {
         a[k]=right[j];
         j++;
       }
 }
 int mergesort(int *a,int n)
{

      if(n<2) return 0;
      int mid=n/2;
      int *left=new int[mid];
      int *right=new int[n-mid];

    for(int i=0;i<=mid-1;i++)
    {
      left[i]=a[i];
     }
     for(int i=mid;i<=n-1;i++)
     {
       right[i]=a[i];
     }
      mergesort(left,mid);
      mergesort(right,n-mid);
      merge(left,mid,right,n-mid,a);
     delete[]left;
     delete[]right;
    }

   int main() {
       //code
      int a[]={10,7,8,9,4,2,3,6,5,1};
      int n=sizeof(a)/sizeof(a[0]);
      mergesort(a,n);
      for(int i=0;i<10;i++)
      {
       cout<<a[i]<<"\t";
      }
      return 0;
       } 

【问题讨论】:

  • 为什么不使用std::vector 而不是原始指针?
  • 我对 std::vector 的作用知之甚少。所以你能告诉我可以在基本代码之上的 d 中进行哪些更改吗?
  • @sneha - 我发布了一个答案,其中仅包含修复基本代码所需的更改。

标签: c++ sorting data-structures merge


【解决方案1】:

cmets 中提到的修复,现在似乎正在工作。在主函数或辅助函数中一次性分配临时数组会更快。使用相互递归函数(一个合并 AtoA,另一个合并 AtoTemp,它们相互调用),无需复制数据。如果需要,我可以稍后发布一个示例。自下而上的归并排序会稍微快一些。

#include <iostream>

using namespace std;

// fix return type to void
void merge(int *left,int nl,int *right,int nr,int *a)
{
    int i=0,j=0,k=0;
    while(i<nl && j<nr)
    {
        if(left[i]<right[j])
        {
            a[k]=left[i];
            i++;
        }
        else
        {
            a[k]=right[j];
            j++;
        }
        k++;
    }
    while(i<nl)
    {
        a[k]=left[i];
        i++;
        k++;                    // fix
    }
    while(j<nr)
    {
        a[k]=right[j];
        j++;
        k++;                    // fix
    }
}

// fix return type to void
void mergesort(int *a,int n)
{
    if(n<2) return;             // fix: change return type to void
    int mid=n/2;
    int *left=new int[mid];
    int *right=new int[n-mid];

    for(int i=0;i<=mid-1;i++)
    {
        left[i]=a[i];
    }
    for(int i=mid;i<=n-1;i++)
    {
        right[i-mid]=a[i];      // fix
    }
    mergesort(left,mid);
    mergesort(right,n-mid);
    merge(left,mid,right,n-mid,a);
    delete[]left;
    delete[]right;
}

int main() {
    //code
    int a[]={10,7,8,9,4,2,3,6,5,1};
    int n=sizeof(a)/sizeof(a[0]);
    mergesort(a,n);
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<"\t";
    }
    cout << endl;               // added this not needed
    return 0;
}

清理,将输出更改为不使用标签:

#include <iostream>
#include <iomanip>              // for std::setw()

using namespace std;

void merge(int *left,int nl,int *right,int nr,int *a)
{
    int i=0,j=0,k=0;
    while(i<nl && j<nr)
    {
        if(left[i]<right[j])
            a[k++]=left[i++];
        else
            a[k++]=right[j++];
    }
    while(i<nl)
        a[k++]=left[i++];
    while(j<nr)
        a[k++]=right[j++];
}

void mergesort(int *a,int n)
{
    if(n<2)
        return;
    int mid=n/2;
    int *left=new int[mid];
    int *right=new int[n-mid];

    for(int i=0;i<=mid-1;i++)
        left[i]=a[i];
    for(int i=mid;i<=n-1;i++)
        right[i-mid]=a[i];
    mergesort(left,mid);
    mergesort(right,n-mid);
    merge(left,mid,right,n-mid,a);
    delete[]left;
    delete[]right;
}

int main() {
    int a[]={10,7,8,9,4,2,3,6,5,1};
    int n=sizeof(a)/sizeof(a[0]);
    mergesort(a,n);
    for(int i=0;i<10;i++)
        cout<<setw(2)<<a[i]<<" ";  // 2 digit field output
    cout << endl;
    return 0;
}

【讨论】:

  • 该死的,你打败了我! :-) 我也在研究它,我还在merge() 中找到了丢失的k++,但我仍在寻找另一个错误。现在我看到了您的解决方案,它看起来很明显......做得好!
  • @FabioTurati - right[i-mid] 是另一个修复方法。如果没有该修复,堆将会损坏,但我想知道该程序是否会以其他方式工作。
  • 我第一次尝试修复程序是创建leftright,大小为n,即过度配置它们。这与其说是一个深思熟虑的想法,不如说是一个猜测,但正如我所料,该程序确实停止了崩溃。但是输出是垃圾;不,它似乎不起作用。所以我开始调试它,我发现了丢失的k++,但我没有对另一行给予足够的关注。然后我看到有一个答案,我无法抗拒检查它的诱惑......:-)
【解决方案2】:

您应该使用std::vector 而不是原始指针:

typedef std::vector<int> ivector;

void merge( const ivector &l, const ivector &r, ivector &to )
{
     ivector_const::iterator il = l.begin();
     ivector_const::iterator ir = r.begin();
     ivector::iterator ito = to.begin();

     while( true ) {
         if( il == l.end() ) {
              if( ir == r.end() ) 
                  return;
              *ito++ = *ir++;
         } else {
              if( ir == r.end() || *il < *ir )
                  *ito++ = *il++;
              else
                  *ito++ = *ir++;
         }
    }
}

void mergesort( ivector &v )
{
      if(v.size()<2) return;
      ivector::iterator imid = v.begin() + v.size() / 2;
      ivector left( v.begin(), imid );
      ivector right( imid, v.end() );

      mergesort(left);
      mergesort(right);
      merge( left, right, v );
}

int main() {
    //code
    ivector a ={10,7,8,9,4,2,3,6,5,1};
    mergesort(a);
    for(size_t i=0;i<a.size();i++)
    {
       cout<<a[i]<<"\t";
    }
    return 0;
} 

注意:我没有验证您的算法,只是用std::vector 而不是原始指针重写了它。您会注意到,当您使用正确的数据类型时,您的函数变得多么简单。

【讨论】:

  • 不使用std::vector还有其他方法吗?
  • @sneha 是的,运行调试器并检查您的长代码并尝试了解那里出了什么问题。
猜你喜欢
  • 2017-06-15
  • 1970-01-01
  • 2016-01-18
  • 1970-01-01
  • 2016-03-21
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
相关资源
最近更新 更多