Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 改进合并排序。改进(3)。在输入阵列和临时阵列之间少使用一个副本_C_Algorithm_Sorting_Merge - Fatal编程技术网

C 改进合并排序。改进(3)。在输入阵列和临时阵列之间少使用一个副本

C 改进合并排序。改进(3)。在输入阵列和临时阵列之间少使用一个副本,c,algorithm,sorting,merge,C,Algorithm,Sorting,Merge,我目前正在为我的算法类做一个项目,现在有点停滞不前。我们被指派通过实现特定的更改来改进合并排序,这在书中有提到。我在前两次改变中表现良好,但第三次是致命的 我们正在改进的Merge-sort将输入数组的内容复制到临时数组中,然后将临时数组复制回输入数组中。因此,它递归地对输入数组进行排序,将两个已排序的部分放入临时数组中。然后,它将临时数组中的两部分合并在一起,将排序后的序列放入输入数组中 改进之处在于,这种双重复制是浪费的,不需要复制即可完成。他的暗示是:我们可以使每个合并调用只在一个方向上复

我目前正在为我的算法类做一个项目,现在有点停滞不前。我们被指派通过实现特定的更改来改进合并排序,这在书中有提到。我在前两次改变中表现良好,但第三次是致命的

我们正在改进的Merge-sort将输入数组的内容复制到临时数组中,然后将临时数组复制回输入数组中。因此,它递归地对输入数组进行排序,将两个已排序的部分放入临时数组中。然后,它将临时数组中的两部分合并在一起,将排序后的序列放入输入数组中

改进之处在于,这种双重复制是浪费的,不需要复制即可完成。他的暗示是:我们可以使每个合并调用只在一个方向上复制,但合并调用会改变方向

这应该是通过模糊原始数组和临时数组之间的线来实现的

我并不是真的在寻找代码,因为我相信我可以编写这段代码。我只是不知道我该做什么。教授今天不在,所以我要到下周我再上他的课时才能问他

以前有人做过这样的事吗?或者可以为我破译并用外行术语解释:P

第一个改进是,只要数组变得足够小,它就可以使用插入排序,这样做在时间上会大大受益

第二个改进停止分配两个动态数组(已排序的两个半数组),而是分配一个大小为n的数组,这是用来代替两个动态数组的。这是我做的最后一件事。其代码为:

//#include "InsertionSort.h"
#define INSERTION_CUTOFF 250
#include <limits.h>  // needed for INT_MAX (the sentinel)
void merge3(int* inputArray, int p, int q, int r, int* tempArray)
{
  int i,j,k;
  for (i = p; i <= r; i++)
  {
    tempArray[i] = inputArray[i];
  }
  i = p;
  j = q+1;
  k = p;
  while (i <= q && j <= r)
  {
    if (tempArray[i] <= tempArray[j])
    {
      inputArray[k++] = tempArray[i++];
    }
    else
    {
      inputArray[k++] = tempArray[j++];
    }
  }
}//merge3()

void mergeSort3Helper(int* inputArray, int p, int r, int* tempArray)
{
  if (r - p < INSERTION_CUTOFF)
  {
    insertionSort(inputArray,p,r);
    return;
  }
  int q = (p+r-1)/2;
  mergeSort3Helper(inputArray,p,q,tempArray);
  mergeSort3Helper(inputArray,q+1,r,tempArray);
  merge3(inputArray,p,q,r,tempArray);
}//mergeSort3Helper()

void mergeSort3(int* inputArray, int p, int r)
{
  if (r-p < 1)
  {
    return;
  }
  if (r - p < INSERTION_CUTOFF)
  {
    insertionSort(inputArray,p,r);
    return;
  }
  int* tempArray = malloc((r-p)+1*sizeof(int));
  tempArray[r+1] = INT_MAX;
  mergeSort3Helper(inputArray,p,r,tempArray);
//  This version of merge sort should allocate all the extra space
//  needed for merging just once, at the very beginning, instead of
//  within each call to merge3().
}//mergeSort3()    
/#包括“InsertionSort.h”
#定义插入切点250
#包括//INT_MAX(哨兵)所需
void merge3(int*inputArray、int p、int q、int r、int*tempArray)
{
int i,j,k;

对于(i=p;i算法如下:
A1:70295143
A2:(未初始化)

第一步:
A1:不变
A2:07291534

第二步:
A1:02791435
A2:不变

第三步:
A1:不变
A2:011234579


这涉及到你每次只复制一种方式,并遵循mergesort的步骤。正如你的教授所说,你通过交替选择which is which来模糊工作数组和排序数组之间的界限,并且只在事物排序后复制。

我怀疑避免所有复制是困难的,最终也是无利可图的。你想要什么改为避免当前在每次合并时进行的复制

您当前的
merge3(inputArray,p,q,r,tempArray)
返回原始数组中的合并结果,这需要一个副本;它仅将其
tempArray
缓冲区用作资源。为了做得更好,您需要将其修改为类似
merge4(inputArray,p,q,r,outputArray)的内容
,其中结果返回到第二个缓冲区,而不是第一个缓冲区

您需要更改
mergeSort3Helper()
中的逻辑来处理此问题。一种方法需要将类似的接口更改为
mergeSort4Helper(inputArray,p,q,r,outputArray)
,这样它也会在第二个缓冲区中生成结果。这将需要最低级别的副本(插入排序)级别,并且如果希望最终结果与它进入的缓冲区相同,则在顶级
mergeSort4()
中添加第二个副本。但是,它会消除所有其他不必要的副本

或者,您可以向
mergeSort4Helper()
添加一个布尔参数,以指示是否希望在第一个或第二个缓冲区中返回结果。此值将以递归方式交替,从而在最低级别上最多生成一个副本


最后一个选项可能是以非递归方式进行合并,并在每次传递时交替使用缓冲区。这也将导致最多一个副本;但是,我希望生成的访问模式本质上比递归模式更不利于缓存。

我假设书中有此算法的代码/伪代码。您可以发布帽子?嗯,我已经对合并排序做了其他3项改进,确实与原来的合并排序相差很远。所以我们的想法是,我们应该使用以前的改进作为这项改进的起点。所以我将发布以前的改进。呃,对不起,其他2项改进。打字。好的,这有助于我理解这一点好多了,但我现在的困惑在于,我应该复制到哪里?看,作为一个提示,我们正在处理的文件中有3个部分。一个是mergeSort4(因为mergesort1只是stand mergessort)然后我们有mergeSort4Helper和merge4。现在我做的最后一次合并排序,我发布了,但我将进入重要的一点,我在mergeSort3中处理临时数组,递归排序输入数组mergeSort3Helper,在那里调用merge3将输入数组复制到temp中,在temp中合并两部分输入数组,然后复制回temp。我不知道我不知道从哪里开始交替。我知道,我知道,但我不知道我应该放弃哪种复制,或者我应该放弃哪种复制。而且,奇数数组不会出现问题吗?可能无法进行最后的交替以放回输入数组?或者我应该有条件根据这一点返回输入数组或临时数组?最后,我使用了对insertionSort的调用来实际执行递归排序(不是合并两个已排序的半部分,只是首先对这两个半部分进行排序,这就是我使用insertionSort的目的)@neojb1989您只需交换inputArray和tempArray的地址。因此,如果在递归级别i,将数组1作为inputArray,将数组2作为tempArray,则交换它们并将其馈送到下一级别,以便将数组2视为inputArray