合并排序,使用文件的I/O显示分段错误 C++编写的以下合并程序在输入通过控制台输入时无任何错误。但是当我使用文本文件输入时,它会给我一个分割错误。我试着在代码的各个部分打印消息,以检查错误在哪里,但除了d seg故障消息外,它没有打印任何内容。 这是代码。当我不使用文件提供输入/显示输出时,它工作正常

合并排序,使用文件的I/O显示分段错误 C++编写的以下合并程序在输入通过控制台输入时无任何错误。但是当我使用文本文件输入时,它会给我一个分割错误。我试着在代码的各个部分打印消息,以检查错误在哪里,但除了d seg故障消息外,它没有打印任何内容。 这是代码。当我不使用文件提供输入/显示输出时,它工作正常,c++,segmentation-fault,mergesort,C++,Segmentation Fault,Mergesort,我在virtualbox 4.0.8(ubuntu操作系统)的gcc编译器上运行了这个程序,基本内存为1GB。原因是内存不足吗 #include<iostream> #include<fstream> #include<sys/time.h> using namespace std; int array[50]; int barray[50]; void merge(int p,int q, int r) { int i,j,k,l; l

我在virtualbox 4.0.8(ubuntu操作系统)的gcc编译器上运行了这个程序,基本内存为1GB。原因是内存不足吗

#include<iostream>
#include<fstream>
#include<sys/time.h>
using namespace std;

int array[50];
int barray[50];

void merge(int p,int q, int r)
 {
    int i,j,k,l;
    l=p;
    i=p;
    j=q+1;

    while((i<=q)&&(j<=r))
    {

     if(array[i]<=array[j])
        barray[++k]=array[i++];

     else
        barray[k++]=array[j++];

    }

    if(i>q)
    {  
       for(l=j;l<=r;l++)
       { 
         barray[k]=array[l];
         k++;
       }
    }

   else
   {
      for(l=i;l<=q;l++)
      {
        barray[k]=array[l];
        k++;
      }

   }

   for(i=p;i<=r;i++)
        array[i]=barray[i];
}

void mergesort(int p, int r)
{
   int q;

   if(p<r)
      q=(p+r)/2;

   mergesort(p,q);
   mergesort(q+1,r);
   merge(p,q,r);

}


int main()
{
  int r, p, i;

  struct timeval tv1, tv2;/* For finding the running time */
  gettimeofday(&tv1, NULL);

  ifstream fin;
  ofstream fout;

  fin.open("abc5.txt");
  fout.open("new5.txt");

  fin>>r;
  while(fin)
  {

    for(i=1;i<=r;++i)
    {
       fin>>array[i];
    }

  }

  mergesort(1,r);

  for(i=1;i<=r;++i)
  {
    fout<<array[i]<<"\n";
  }

  gettimeofday(&tv2, NULL);
  fout<<"Running Time: "<<(double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double)    (tv2.tv_sec - tv1.tv_sec)<<" sec";


 fin.close();
 fout.close();

 return 0;

}
#包括
#包括
#包括
使用名称空间std;
int数组[50];
英特巴拉伊[50];
无效合并(int p,int q,int r)
{
int i,j,k,l;
l=p;
i=p;
j=q+1;

虽然((i所以给定您的输入,但当p=1和r=1时,您在随后的mergesort调用中使用未初始化的q值


您收到的错误是因为mergesort函数中存在无限递归。

您的索引还有很多需要改进的地方。我会毫不犹豫地告诉您,也不会简单地说我不会以这种方式进行合并排序。但这就是问题所在,所以我将介绍它

重要的是要理解,使用分治算法的序列排序都是关于在序列中传递一些基本引用和该引用的一些偏移量。该算法应该独立于外部变量(如
array[]
barray[]
)然后把它们作为参数,记住,你在C++编程中(或C)这两种语言的一部分优点是它们的本地指针算术能力。它可以很好地用于像归并排序之类的算法。在演示了合并和合并函数应该如何工作之后,我将演示我所说的,然后我将介绍在使用C++时,C++中可以做的最简单的归并排序。库功能


先输入代码

首先,使用您的参数重新启动函数。我已经冒昧地将参数重命名为它们对审阅者来说实际上是有意义的。算法应该是不言自明的,我敦促您将其与您所做的并排进行比较

//  low  = starting index
//  mid  = middle index
//  high = last index
void merge(int low, int mid, int high)
{
    int i=low, j=mid, k=0;

    while (i < mid && j <=high)
    {
        if (array[i] < array[j])
            barray[k++] = array[i++];
        else
            barray[k++] = array[j++];
    }

    // finish whichever segment isn't done
    while (i < mid)
        barray[k++] = array[i++];
    while (j <= high)
        barray[k++] = array[j++];

    // copy back
    for (i=0;i<k;++i)
        array[low+i] = barray[i];
}

void mergesort(int low, int high)
{
    int len = high - low;
    if (len < 2)
        return;

    int mid = low + len/2;
    mergesort(low, mid);
    mergesort(mid, high);
    merge(low, mid, high);
}
输出(不同)


你会讨厌的部分

在完成所有这些工作之后,您将不会很高兴地知道标准库中已经存在两种为您进行段合并的算法,即and。使用其中一种算法会使实现
mergesort
变得微不足道,如下所示:

#include <algorithm>

void mergesort(int ar[], std::size_t len)
{
    if (len < 2)
        return;

    mergesort(ar, len/2);
    mergesort(ar+len/2, len-len/2);
    std::inplace_merge(ar, ar+len/2, ar+len);
}
#包括
无效合并排序(int-ar[],std::size\u t len)
{
if(len<2)
返回;
合并排序(ar,len/2);
合并排序(ar+len/2,len-len/2);
标准:就地合并(ar,ar+len/2,ar+len);
}

请记住,如果您需要使用除
std::sort
之外的其他内容,那么除了满足学术目的之外,这一切几乎都是无用的。

也可以发布输入文件,因为输入文件最好不要超过50行。如果是,则与基于1和基于0的不正确使用C/C++数组很容易调用UB。注意:在将其用作合并算法中解引用的索引之前,您从未初始化过
k
。仅此一项就将调用未定义的行为。此外,请检查两个主要赋值中
k
的增量。它不一致,必须一致。老实说,合并算法只是n需要彻底返工。Sry不得不吃午饭。此外,如果
(PI只尝试了8个元素,它也不适用。WhozCraig说……你能发布你的输入吗?谢谢你指出这一点!但是即使在初始化Q和K并将索引改为0个数组之后,它仍然显示SEG错误!我想WhozCraig已经给出了答案。你应该考虑改写你的算法。也就是说,如果你想知道这个实现为什么会这样,你可能想启动GDB,并在它运行时逐步完成它。学习使用GDB将在你未来的职业生涯中获得回报。这可能与课堂作业有关,而不是他推出自己的实现。@AlbertMyers我同意,在suc中h情况下,我不会像其他很多人一样跳上“just use std::sort”的潮流。这是三部分答案的要点:(a)这就是你的代码的问题,(b)这是一种不同的方式,以及(c)这是最简单的工作方式。希望有一天,“我不必这么做,因为它已经在库中了”的安慰会起作用。
15 10 8 38 20 21 9 43 8 22 19 45 12 16 17 36 2 32 6 37 
2 6 8 8 9 10 12 15 16 17 19 20 21 22 32 36 37 38 43 45 
#include <algorithm>

void mergesort(int ar[], std::size_t len)
{
    if (len < 2)
        return;

    mergesort(ar, len/2);
    mergesort(ar+len/2, len-len/2);
    std::inplace_merge(ar, ar+len/2, ar+len);
}