[英]Merge sort algorithm in ANSI C
I'm learning ANSI C and for a class I have to implement a merge sort algorithm in it.我正在学习 ANSI C,对于 class,我必须在其中实现合并排序算法。 I'm following the book's guide.
我正在按照本书的指南进行操作。 But, for some reason I can't have it working.
但是,由于某种原因,我无法让它工作。
Only two digits from my list got in the right position.我的列表中只有两位数字在正确的 position 中。 And for the others, new digits are created.
而对于其他人,则创建了新的数字。 I have no idea why this happens, I think it is the way I create the temp arrays
L
and R
(I'm using 1.0 / 0.0
to set the last element to +INFINITY
).我不知道为什么会发生这种情况,我认为这是我创建临时 arrays
L
和R
的方式(我使用1.0 / 0.0
将最后一个元素设置为+INFINITY
)。 But I'm not sure if that is the reason.但我不确定这是否是原因。
Here is my code so far:到目前为止,这是我的代码:
/* C program for Merge Sort */
#include <stdio.h>
#include <stdlib.h>
void printArray(int A[], int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
void merge(int arr[], int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1 + 1], R[n2 + 1];
for (i = 1; i <= n1; i++) {
L[i] = arr[l + i - 1];
}
for (j = 1; j <= n2; j++) {
R[j] = arr[m + j];
}
L[n1 + 1] = 1.0 / 0.0;
R[n2 + 1] = 1.0 / 0.0;
i = 1;
j = 1;
for (k = l; k <= r; k++) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
}
// If I delete this the code stop "working". Why???
while (i < k && k < i) {
i++;
}
}
void mergeSort(int arr[], int left, int right) {
if (left < right) {
int middle = left + (right - left) / 2;
mergeSort(arr, left, middle);
mergeSort(arr, middle + 1, right);
merge(arr, left, middle, right);
}
}
int main() {
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("Given array is \n");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;
}
Also, for some reason beyond my humble understanding when i delete the while
block, that does nothing apparently, the code stops working.此外,由于某些原因超出了我的理解,当我删除
while
块时,显然没有任何作用,代码停止工作。 Can someone give me a light on this?有人可以告诉我这个吗?
The problem lies in your attempt to use 'infinity'.问题在于您尝试使用“无穷大”。 Your data are integer values, and there is no representation of infinity in the integral types.
您的数据是integer值,整数类型中没有无穷大的表示。
To set a "maximum possible value," use the pre-defined INT_MAX
constant.要设置“最大可能值”,请使用预定义的
INT_MAX
常量。 So, replace the following lines:因此,替换以下行:
L[n1 + 1] = 1.0 / 0.0;
R[n2 + 1] = 1.0 / 0.0;
with:和:
L[n1 + 1] = INT_MAX;
R[n2 + 1] = INT_MAX;
Also, as you access the [n1 + 1]
and [n2 + 1]
elements of the L
and R
arrays, you will need to increase the size of each of those arrays by one (arrays in C start at zero and end at 'n' - 1). Also, as you access the
[n1 + 1]
and [n2 + 1]
elements of the L
and R
arrays, you will need to increase the size of each of those arrays by one (arrays in C start at zero and end at ' n' - 1)。 Like so:像这样:
int L[n1 + 2], R[n2 + 2]; // So we can use the `... + 1` elements.
With these changes, the code you posted works (even removing the strange while
loop at the end of your merge
function).通过这些更改,您发布的代码可以正常工作(甚至在
merge
函数末尾删除奇怪的while
循环)。
Note: Although your 1.0/0.0
does produce a floating point representation of infinity, attempting to cast/convert that value to an int
produces Undefined Behaviour.注意:尽管您的
1.0/0.0
确实会产生无穷大的浮点表示,但尝试将该值强制转换/转换为int
会产生未定义的行为。 See: What is the result of casting float +INF, -INF, and NAN to integer in C?请参阅:在 C 中将浮点 +INF、-INF 和 NAN 转换为 integer 的结果是什么?
As to why that strange while
loop was 'required' to make your code (not quite) work: Well, once undefined behaviour is invoked, anything can happen (including the summoning of Nasal Demons from the ether).至于为什么“需要”那个奇怪的
while
循环来让你的代码(不完全)工作:好吧,一旦调用了未定义的行为,任何事情都可能发生(包括从以太中召唤鼻恶魔)。 See: Undefined, unspecified and implementation-defined behavior请参阅:未定义、未指定和实现定义的行为
There is my merge sort algorithm, and the function returns the number of inversions.有我的归并排序算法,function 返回倒数。
int merge(int array[], int tempArray[],
size_t left, size_t middle1, size_t middle2, size_t right)
{
size_t leftIndex = left, rightIndex = middle2, combinedIndex = left;
int inversions = 0;
while (leftIndex <= middle1 && rightIndex <= right)
{
if (array[leftIndex] <= array[rightIndex])
{
tempArray[combinedIndex++] = array[leftIndex++];
}
else
{
tempArray[combinedIndex++] = array[rightIndex++];
inversions += middle2 - leftIndex;
}
}
while (leftIndex <= middle1)
{
tempArray[combinedIndex++] = array[leftIndex++];
}
while (rightIndex <= right)
{
tempArray[combinedIndex++] = array[rightIndex++];
}
for (size_t i = left; i <= right; i++)
{
array[i] = tempArray[i];
}
return inversions;
}
int mergeSort(int array[], int tempArray[], size_t low, size_t high)
{
return low < high ? mergeSort(array, tempArray, low, (low + high) / 2) + mergeSort(array, tempArray, (low + high) / 2 + 1, high) + merge(array, tempArray, low, (low + high) / 2, (low + high) / 2 + 1, high) : 0;
}
int sort(int array[], size_t length)
{
int *tempArray = (int *)malloc(sizeof(int) * length);
return mergeSort(array, tempArray, 0, length - 1);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.