C语言 如何在排序问题中同时满足时间复杂度和空间复杂度?

juzqafwq  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(98)

我试图使用冒泡排序算法对数字进行升序排序。但是,我仍然得到一个OufOfMemory错误。
如何确保代码中不会出现OufOfMemory错误?
问题就像下面的句子。

  • 内存容量限制为8 MB。
    *时间限制为5秒。
  • 第一行给出了数N(1 ≤ N ≤ 10,000,000)的个数。
  • 从第二行开始,N行给出数字。该数字是小于或等于10,000的自然数。

https://www.acmicpc.net/problem/10989
下面是我尝试打印的数字的代码。

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

void swap(int* x, int* y){
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

int main(){

    int N, i, j;
    scanf("%d", &N);

    int* arr;
    arr = (int*)malloc(N * sizeof(int));

    for(i=0;i<N;i++){
        scanf("%d", &arr[i]);
    }
    
    int min_value = arr[0];
    for(i=0;i<N;i++){
        for(j=0;j<N-i-1;j++){
            if(arr[j] > arr[j+1]) {
                swap(&arr[j], &arr[j+1]);
            }
        }
    }

    for(i=0;i<N;i++){
        printf("%d\n", arr[i]);
    }

    return 0;
}
#include <stdio.h>
#include <stdlib.h>

void swap(int* x, int* y){
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

int main(){

    int N;
    int i, j;
    scanf("%d", &N);

    long* arr;
    arr = (long*)malloc(N * sizeof(int));

    for(i=0;i<N;i++){
        scanf("%ld", &arr[i]);
    }

    for(i=0;i<N;i++){
        for(j=0;j<N-i-1;j++){
            if(arr[j] > arr[j+1]) {
                swap(&arr[j], &arr[j+1]);
            }
        }
    }

    for(i=0;i<N;i++){
        printf("%ld\n", arr[i]);
    }

    return 0;
}

在猜测内存不足的原因时,似乎是由于动态分配中的N * sizeof(int)引起的内存溢出。如果N的范围为10,000,000,最坏的情况是N * int为2.097.152。结果超出内存。
此外,我计算了8 MB的内存,如下面的句子。
8 * 1024 * 1024 / 4 = 2.097.152
下面是预期的结果:

  • 满足5秒的时间限制。
  • 满足8 MB的内存限制。

This与我的问题有关,但它不能解决我的问题。
感谢您阅读我的文章。

wgx48brx

wgx48brx1#

int可能比存储0..10,000中的数字所需的要大。这实际上是可能的。您可以使用int16_tuint16_t。但是这些数组仍然会占用20 MB或超过19 MiB。这意味着您不可能一次将所有数字放入内存中。
这就排除了冒泡排序。事实上,这排除了所有传统的排序(因为你可能也不能使用外部存储)。
但是因为我们要对小数字进行排序,所以我们可以使用非常规的排序方法,例如Counting Sort。我们需要一个包含10,001个uint32_t对象的数组,也就是说刚刚超过40 KB或低于40 KiB。这远远低于您的限制。
在时间方面,冒泡排序是非常低效的,可能对你的目标来说不够快。
你不会有任何时间问题与计数排序。

相关问题