如果在冒泡排序程序中输入偶数个整数,则在中间插入一个随机数

If entered an even number of integers in bubble sort program a random number is inserted in the middle

我的任务是在使用动态内存时对负数和正数进行排序,因此在这种情况下,我使用 calloc 和冒泡排序在不改变负数顺序的情况下先排列负数。问题是当我输入偶数个整数时,结果中间会出现一些随机的 10 位负数。奇数个整数不会发生同样的情况。好像是什么问题?

#include <stdio.h>
#include <stdlib.h>

#define SIZE 1000

void swap(int *arr, int n) {
    int i, j, temp;
    for (i = 0; i <= n; i++) {
        for (j = 1; j <= n; j++) {
            if (arr[j] < 0) {
                temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
        }
    }
    printf("sorted integers to negative and positive: \n");
    for (i = 0; i < n; i++) {
        printf("%i ", arr[i]);
    }
}

int main() {
    int n;
    int i, *sk;
    printf("Enter integer: \n");
    scanf("%d", &n);
    printf("Enter %i integers: \n", n);
    sk = (int*)calloc(sizeof(int), n);
    for (i = 0; i < n; i++) {
        scanf("%d", sk + i);
    }
    swap(sk, n);
    return 0;
}

这是未定义的行为,仅当您碰巧输入偶数个整数时才会出现,但实际上问题始终存在:您从数组,它会到达数组的中间。

您可以通过将 i <= nj <= n 更改为 i < nj < n 来解决此问题。但是,这不会修复损坏的排序算法,因为交换条件也不正确。而不是

if(arr[j]<0)

应该是

if(arr[j]<arr[j-1])

您的 for 循环中有 2 个经典错误:

for (i = 0; i <= n; i++) 几乎总是错误的,因为循环是 运行 n + 1 次,它应该只枚举从 0n - 1 的索引值。

你在第二个循环中有一个相同的错误:测试 j <= n 让你走得太远了一步,读到数组的末尾之外。一些随机值被混入数组,但这种未定义的行为可能会产生更糟糕的后果。

另外,你的对比测试不正确,应该是if (arr[j] < arr[j-1])

根据经验,每当您在循环测试中看到 <= 运算符时,请再次查看,这可能是一个错误。

这是更正后的版本:

void swap(int *arr, int n) {
    int i, j, temp;
    for (i = 0; i < n; i++) {
        for (j = 1; j < n; j++) {
            if (arr[j] < arr[j - 1]) {
                temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
        }
    }
    printf("sorted integers to negative and positive: \n");
    for (i = 0; i < n; i++) {
        printf("%i ", arr[i]);
    }
    printf("\n");
}