C++ 合并排序不起作用?
我在让我的合并排序函数与教授给我的规范一起工作时遇到了一些问题。一直盯着VS和谷歌想弄清楚这个家伙 算法提供了: 数组函数C++ 合并排序不起作用?,c++,algorithm,sorting,mergesort,C++,Algorithm,Sorting,Mergesort,我在让我的合并排序函数与教授给我的规范一起工作时遇到了一些问题。一直盯着VS和谷歌想弄清楚这个家伙 算法提供了: 数组函数 template<class T> void printArray(T arr[], int numElements) { cout << "("; for (int i = 0; i < numElements; i++) { cout << arr[i]; if (
template<class T>
void printArray(T arr[], int numElements)
{
cout << "(";
for (int i = 0; i < numElements; i++)
{
cout << arr[i];
if (i < numElements - 1)
cout << ", ";
}
cout << ")" << "\n\n";
}
template <class T>
void setArray(T to[], T from[], int size)
{
for (int i = 0; i < size; i++)
to[i] = from[i];
}
template <class T>
void setArray(T to[], T from[], int size1, int size2)
{
int size = size1;
if (size2 < size1) size = size2;
setArray(to, from, size);
}
模板
无效打印数组(T arr[],整数)
{
库特
这是破坏合并的代码部分,考虑一下如果两个列表中多了一个元素,那么会发生什么,请参见:
// Create Temporary Arrays
T * tmp1 = new T[size1 + 1]();
T * tmp2 = new T[size2 + 1]();
这意味着对于2个值,它们可能看起来像这样
foo = [1,2,?]
bar = [3,4,?]
问号将是一些数字,但你无法知道是什么,如果你在循环中运行比较几次,你将得到让我们说i=2,j==0为简单起见,现在你尝试进行比较:
if (foo[2] <= bar[0])
if(foo[2]这是一个简单的一次性错误
T * tmp1 = new T[size1 + 1]();
...
tmp1[size1 + 1] = numeric_limits<T>::max();
^^^
T*tmp1=新的T[size1+1]();
...
tmp1[size1+1]=数值限制::max();
^^^
数组索引从0
到n-1
,而不是n
第1期:哨兵
infinity
被注释掉是问题之一
// tmp1[size1] = (infinity?)
// tmp2[size2] = (infinity?)
它用作哨兵,因此当您到达tmp1
(或tmp2
)的最后一个位置时,它将确保您从另一个数组tmp2
(或tmp1
)复制所有其他元素。您可以在此处使用std::numeric\u limits::max()
表示inf
@Petter很好地描述了为什么会发生这个问题
问题2:初始化
您的另一个问题似乎是在合并阵列之前的初始化:
int i = 1;
int j = i;
伪代码从1
索引,而它应该从0
开始
问题3:索引
正如@MarkRansom所指出的,索引范围应该是从0
到size1
,而不是size1+1
tmp1[size1 + 1] = numeric_limits<T>::max();
tmp1[size1+1]=数值限制::max();
< /代码> 在C++合并函数中,L[]的右半部分以中+ 1开头,因此第二个填充环应该是:
for (int j = 0; j < size2; j++)
tmp2[j] = L[mid + j + 1];
for(int j=0;j
在所提供的算法中,索引从1到n,因此第一个填充循环是TMP1[i]← L([LeLeLoop+i 1)],用C++,索引从0变为N-1,因此C++首先填充循环:TMP1[i]=L[LoeLef+I];是正确的,但是第二个环需要改变为TMP2 [j]=L[Me+J+1 ]; < P>抱歉忘记回答近两个星期://P>
这是一个接一个的错误,但我找到了他们,并使其工作。
感谢所有帮助过我的人
改变
int size1 = mid - lowerBound;
int size2 = upperBound - mid;
for (int j = 0; j < size2; j++)
tmp2[j] = L[mid + j];
for (int k = lowerBound; k < upperBound; k++)
{
if (tmp1[i] <= tmp2[j])
{
L[k] = tmp1[i];
i++;
}
else
{
L[k] = tmp2[j];
j++;
}
}
到
改变
int size1 = mid - lowerBound;
int size2 = upperBound - mid;
for (int j = 0; j < size2; j++)
tmp2[j] = L[mid + j];
for (int k = lowerBound; k < upperBound; k++)
{
if (tmp1[i] <= tmp2[j])
{
L[k] = tmp1[i];
i++;
}
else
{
L[k] = tmp2[j];
j++;
}
}
for(int j=0;j
到
for(int j=0;j
改变
int size1 = mid - lowerBound;
int size2 = upperBound - mid;
for (int j = 0; j < size2; j++)
tmp2[j] = L[mid + j];
for (int k = lowerBound; k < upperBound; k++)
{
if (tmp1[i] <= tmp2[j])
{
L[k] = tmp1[i];
i++;
}
else
{
L[k] = tmp2[j];
j++;
}
}
for(int k=lowerBound;k if(tmp1[i]当您使用调试器时,哪些行或变量导致了问题?setArray做了什么?您测试了它吗?它工作正常吗?投票关闭--没有证据表明O.P.使用了调试器。我不想浪费时间试图让代码编译并在其上为O.P>使用调试器。为什么您的sentinelinfinity
被注释掉了吗?你不能使用std::numeric\u limits::max()
?我想这就是问题所在。因为你没有哨兵,所以你在size1+1
或size2+1
位置复制垃圾。我没有收到任何编译错误或致命的运行时错误,所以我不确定。“总之,(无穷大?)以某种聪明的方式。”-可能这就是分配数值限制::max()
的行试图做的事情。@davmac那是因为他改变了问题。在我建议数值限制::max()
之前,它是(无穷大?)
行被注释掉了。@davmac是的,但由于这看起来像是学校的作业,我认为给出正确答案可能是徒劳的。@davmac没问题!:)我解释说,因为我实际上认为他不应该改变它,因为这是问题的一部分。谢谢,刚刚抓住了这一点。哦,拜托,关于原始新?:)@TemplateRex这显然是家庭作业,学习如何处理原始指针很有用,即使你再也不用了。
for (int k = lowerBound; k < upperBound; k++)
{
if (tmp1[i] <= tmp2[j])
{
L[k] = tmp1[i];
i++;
}
else
{
L[k] = tmp2[j];
j++;
}
}
for (int k = lowerBound; k <= upperBound; k++)
{
if (tmp1[i] <= tmp2[j])
{
L[k] = tmp1[i];
i++;
}
else
{
L[k] = tmp2[j];
j++;
}
}