【问题标题】:Time Complexity between Bubble and Insertion冒泡和插入之间的时间复杂度
【发布时间】:2015-10-02 00:21:12
【问题描述】:

我在 C 中实现了 3 个排序对数:冒泡排序、插入排序和快速排序。当我测试算法的运行时间时,插入常量的运行速度比冒泡排序快得多。通过此链接http://bigocheatsheet.com/
,我被引导相信他们应该在同一时间 谁能解释一下为什么插入排序要快得多?

#define _CRT_SECURE_NO_WARNINGS

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

void insertSort(int arr[], int size){
    int temp, j, i;

    for (i = 1; i < size; i++){
        temp = arr[i];
        for (j = i; j > 0 && temp < arr[j - 1]; j--){
            arr[j] = arr[j - 1];
        }
        arr[j] = temp;
    }
}

void quicksort(int arr[], int first, int last){
    int pivot, j, temp, i;

    if (first < last){
        pivot = first;
        i = first;
        j = last;

        while (i < j){
            while (arr[i] <= arr[pivot] && i < last)
                i++;
            while (arr[j] > arr[pivot])
                j--;
            if (i < j){
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        temp = arr[pivot];
        arr[pivot] = arr[j];
        arr[j] = temp;
        quicksort(arr, first, j - 1);
        quicksort(arr, j + 1, last);
    }
}

void bubbleSort(int arr[], int size){
    int x = 0, y;

    for (x; x < size; x++){
        for (y = 0; y < size - 1; y++){
            if (arr[y] > arr[y + 1]){
                int temp = arr[y + 1];
                arr[y + 1] = arr[y];
                arr[y] = temp;
            }
        }
    }
}

void printArray(int arr[], int sizeArray){
    int i = 0;
    for (i; i < sizeArray; i++){
        printf("%i\n", arr[i]);
    }

    //  printf("\n");
    //  for (i = 0; i < number; i++){
    //      printf("bubbleNums[%d] = %d     ", i, *(bubbleNums + i));
    //      printf("insertNums[%d] = %d     ", i, *(insertNums + i));
    //      printf("quickNums[%d] = %d\n", i, *(quickNums + i));
    //  }
}

int main(){
    int *bubbleNums = (int *)malloc(100000 * sizeof(int)), *quickNums = (int *)malloc(100000 * sizeof(int)), *insertNums = (int *)malloc(100000 * sizeof(int));
    int number;
    int randNumber;
    int i = 0;

    printf("Enter a number: ");
    scanf(" %i", &number);

    printf("\n");
    srand(100);
    for (i; i < number; i++){
        randNumber = rand() % 100;
        bubbleNums[i] = randNumber;
        insertNums[i] = randNumber;
        quickNums[i] = randNumber;
        //      printf("bubbleNums[%d] = %d     ", i, *(bubbleNums + i));
        //      printf("insertNums[%d] = %d     ", i, *(insertNums + i));
        //      printf("quickNums[%d] = %d\n", i, *(quickNums + i));
    }

    printf("\n");
    clock_t t0 = clock();
    bubbleSort(bubbleNums, number);
    clock_t t1 = clock();
    printf("Time to sort bubblesort of %i elements: %d milliseconds\n", number, (t1 - t0));

    clock_t t2 = clock();
    insertSort(insertNums, number);
    clock_t t3 = clock();
    printf("Time to sort insertSort of %i elements: %d milliseconds\n", number, (t3 - t2));

    clock_t t4 = clock();
    quicksort(quickNums, 0, number - 1);
    clock_t t5 = clock();
    printf("Time to sort quicksort of %i elements: %d milliseconds\n", number, (t5 - t4));

        //printf("Bubble\n");
        //printArray(bubbleNums, number);
        //printf("Insert\n");
        //printArray(insertNums, number);
        //printf("Quick\n");
        //printArray(quickNums, number);

    getchar();
    getchar();

    return 0;
}

【问题讨论】:

    标签: c sorting time-complexity


    【解决方案1】:

    O(...) 不包括常数乘数或低阶项。因此,如果一种方法的时间是 2 x n^2,而另一种方法的时间是 6 x n^2 + 12 x n + 18,则它们都被认为是 O(n^2),即使其中一种方法的速度是第一种方法的 3 倍以上。其他。

    O(...) 只是为您提供特定算法的时间与 n 的关系的一阶近似值。

    对于另一个问题,插入排序更快,因为它会根据需要旋转数组的一部分,而冒泡排序只交换对。

    【讨论】:

    • .....我忘记了常数乘数。自从我完成 O 符号以来已经很久了,我完全忘记了它。谢谢!
    【解决方案2】:

    这可能是因为您的 BubbleSort 在列表排序时没有停止。您应该跟踪每次通过的更改次数。如果没有任何更改,则对列表进行排序。现在你强迫它总是有最差的性能。

    for (x; x < size; x++){
        int changes = 0;
        for (y = 0; y < size - 1; y++){
            if (arr[y] > arr[y + 1]){
                int temp = arr[y + 1];
                arr[y + 1] = arr[y];
                arr[y] = temp;
                changes++;
            }
        }
        if (changes == 0) {
            return;
        }
    }
    

    【讨论】:

    • 这是修改冒泡排序的算法。这是它的一个有效版本,并且是一个更好的版本。即使我在这个版本中使用 10000 个元素运行它,冒泡排序也需要 612 毫秒,而插入需要 119 毫秒。朋友给了我一个建议,它可能与分支有关,但不确定如何。
    【解决方案3】:

    渐近复杂度告诉您性能如何缩放问题的大小。它没有告诉您任何关于同一任务的替代算法在同一问题上相对于其他算法的执行情况。

    插入排序结果是 O(n2) 排序算法中最快的。尽管它的扩展方式与冒泡排序相同,但插入排序往往执行的比较和交换要少得多。减少多少取决于实现细节和输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 2015-05-17
      • 2012-11-23
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      相关资源
      最近更新 更多