我正在C中实现合并排序。我有一个合并函数-merge(int array[],int start,int middle,int end)
和一个mergeSort函数-mergeSort(int*array,unsigned int size)
。
如果对原始数组的前半部分和后半部分进行排序(例如:5,6,7,8,1,2,3,4
),则合并排序可以很好地工作。这是因为我的merge函数无论在什么情况下都要传递原始数组,并且当它被赋予2个排序数组时(正如预期的那样),它可以工作。我的问题是他们什么时候不是。每次调用merge时,我的原始数组都没有被修改,尽管我已经对它进行了编程。有人能知道我的问题在哪里吗?代码在下面。
当我在输入{10,9,8,7,6,5,4,3,2,1}
上运行此代码时,它将返回{5,4,3,2,1,0,10,9,8,7,6}
。
void merge(int arr[], int l, int m, int r) {
int size1 = m - l + 1;
int size2 = r - m;
int arr1[size1];
int arr2[size2];
int i;
for ( i = 0; i < size1; i++ ) {
arr1[i] = arr[l + i];
}
for ( i = 0; i < size2; i++ ) {
arr2[i] = arr[m + i + 1];
}
i = 0;
int j = 0;
int k = 0;
while ( i < size1 && j < size2 ) {
if ( arr1[i] < arr2[j] ) {
arr[k] = arr1[i];
i++;
k++;
} else {
arr[k] = arr2[j];
j++;
k++;
}
}
while ( i < size1 ) {
arr[k] = arr1[i];
i++;
k++;
}
while ( j < size2 ) {
arr[k] = arr2[j];
j++;
k++;
}
}
void mergeSort(int *array, unsigned int size) {
int start = 0;
int middle = (size / 2) - 1;
int end = size - 1;
if ( size < 2 ) {
return;
}
int m = ( size / 2 );
int arr1[m];
int arr2[size - m];
int i;
for ( i = 0; i < middle + 1; i++ ) {
arr1[i] = array[i];
printf("%d\n", arr1[i]);
}
for ( i = middle + 1; i < size; i++ ) {
arr2[i - (middle + 1)] = array[i];
}
mergeSort(arr1, m);
mergeSort(arr2, size - m);
merge(array, start, middle, end);
}
您的代码中存在多个问题:
mergeSort
函数将数组拆分为2个局部数组,并递归调用自身对它们进行排序,但merge
阶段不将这些排序的数组作为输入。您应该直接使用参数数组的部分内容。size
的小值造成问题。使用一个简单的约定:传递end
作为第一个元素经过数组结尾的偏移量。这样计算大小只需从end
减去start
。merge
函数将k
初始化为0
而不是l
。以下是一个修正版本:
void merge(int arr[], int start, int m, int end) {
int size1 = m - start;
int size2 = end - m;
int arr1[size1];
int arr2[size2];
int i, j, k;
for (i = 0; i < size1; i++) {
arr1[i] = arr[start + i];
}
for (i = 0; i < size2; i++) {
arr2[i] = arr[m + i];
}
i = j = 0;
k = start;
while (i < size1 && j < size2) {
if (arr1[i] < arr2[j]) {
arr[k++] = arr1[i++];
} else {
arr[k++] = arr2[j++];
}
}
while (i < size1) {
arr[k++] = arr1[i++];
}
while (j < size2) {
arr[k++] = arr2[j++];
}
}
void mergeSort(int *array, unsigned int size) {
if (size >= 2) {
int m = size / 2;
mergeSort(array, m);
mergeSort(array + m, size - m);
merge(array, 0, m, size);
}
Bob__建议进行简化,只将数组的前半部分保存到ARR1
中,而不需要ARR2
。这里是一个修改版本,还删除了start
(始终为0
)和其他一些简化:
void merge(int arr[], size_t m, size_t size) {
int arr1[m];
size_t i, j, k;
for (i = j = k = 0; j < m; j++) {
arr1[j] = arr[j];
}
while (i < m && j < size) {
if (arr1[i] < arr[j]) {
arr[k++] = arr1[i++];
} else {
arr[k++] = arr[j++];
}
}
while (i < m) {
arr[k++] = arr1[i++];
}
}
void mergeSort(int *array, size_t size) {
if (size >= 2) {
size_t m = size / 2;
mergeSort(array, m);
mergeSort(array + m, size - m);
merge(array, m, size);
}
但是请注意,为arr1
分配自动存储(也就是堆栈上的存储)可能会导致大型数组(通常大于几十万个元素)的未定义行为。从堆中分配临时数组可以避免这个问题,但代价是额外的开销和分配失败的可能性。
在mergeSort
中,在执行mergeSort(arr1,m)
和mergeSort(arr2,size-M)
之后,实际上并没有对arr1
和arr2
执行任何操作。
对于一个简单的修复,我建议不要使用变量ARR1
和ARR2
,而是直接对array
的部分调用mergeSort
,如下所示:
void mergeSort(int* array, unsigned int size) {
int start = 0;
int middle = (size / 2);
int end = size - 1;
if ( size < 2 ) {
return;
}
mergeSort(array, middle);
mergeSort(array + middle, size - middle);
merge(array, start, middle - 1, end);
}
我有一个递归函数,需要创建一个由特殊对象组成的数组... 我的自定义对象由此类填充: 这是我的递归函数: 在这个函数中,RandomBool()方法随机返回true/false。。。RandomId()也不重要。。。 问题在于“位置”数组。我希望每个项目都有特定的位置数组,例如: 对于第一步,每个项目都需要有:[0]、[1]、[2]、[3]。。。 下一步,假设我们选择了3:[3,0],[3,1],
问题内容: 我正在使用一个用于保存和调用屏幕状态的系统,这是我第一次弄这种东西,所以我不确定如何解决此问题的最佳方法是什么,但是我目前存储了所有“ PreviewMonitor”数组列表中的对象(大约40个左右)。问题是,当我创建要存储的名为“ allPreviewMonitors”的ArrayList的副本时,最终得到的ArrayList的元素随着原始元素的更新而不断变化。实际上,好像我正在使用
问题内容: 我有以下字典: 我想将一个条目附加到key1-> key2-> key3上,其值为’blah’,产生: 我正在寻找一种与键的数量无关的通用解决方案,即即使不存在从key3向下的键,key1-> key2-> key3-> key4-> key5也应该起作用。这样我得到: 提前致谢。 问题答案: 您可以使用该函数遍历一系列嵌套字典: 演示: 当密钥不存在时,此版本引发异常: 但您可以替换
本文向大家介绍在JavaScript中使用递归求和数组的修改后的版本,包括了在JavaScript中使用递归求和数组的修改后的版本的使用技巧和注意事项,需要的朋友参考一下 假设,我们需要编写一个递归函数,该求和函数将Numbers数组的所有元素相加,但有一个转折,而转折是我们编写的递归函数不能初始化任何额外的变量(内存)。 就像我们不能使用变量来存储总和或保持数组索引的计数一样,所有这些都必须使用
假设数组A:1,2,3,1,1,3。不同的整数应在数组B中:1,2,3。然后,函数应打印:[1,1][1,2][1,3][2,1][2,2][2,3][3,1][3,2][3,3]。 我试图解决不重复的整数问题,但没有递归 但问题是我必须以递归的方式解决它,有什么想法吗?
我正在尝试优化一个函数,给定一个N int数组,它返回一个元素和前一个元素之间的最小差异。显然,该函数仅适用于具有维度的数组 不知道有没有办法避免在main中传递第一个差,而是在递归函数中做所有的事情。我可以用stdio . h/stdlib . h/string . h/math . h作为头文件。非常感谢你的帮助,我希望这能让我对递归函数有更好的理解。