简体   繁体   English

为什么我的 selectionSort 实现比我的 bubbleSort 实现快?

[英]Why is my implementation of selectionSort faster than my implementation of bubbleSort?

I am trying to implement the selection sort algorithm in c.我正在尝试在 c 中实现选择排序算法。 I don't know whether this is a correct implementation, and why my algorithm is much quicker than bubbles sort.我不知道这是否是一个正确的实现,以及为什么我的算法比冒泡排序快得多。 Therefore, I am asking if you can tell me is correct or not and any improvement I have to make.因此,我问您是否可以告诉我是否正确以及我必须做出的任何改进。

main(){
    
    srand(time(NULL));
    system("color b");
    
    int A[NUM],i;
    
    for(i=0;i<NUM;i++){
        A[i] = rand()%30000;
    }
    
    displayArray(A);
    SelectionSort(A);   
    displayArray(A);
        
    system("pause");
}

void displayArray(int * A){
    
    int i;
    for(i=0;i<NUM;i++){
        printf("%6d ", A[i]);
    }
    printf("\n");
}


void SelectionSort(int * A){
    
    int i,j,k, pos; 
    for(i=0;i<NUM;i++){
    
        k = A[i];
        for(j=i+1;j<NUM;j++){
            if(k >= A[j]){
                pos = j;
                k = A[j];
            }
        }
        A[pos] = A[i];
        A[i] = k;
        
    }
    
}

You should check it with the output of qsort() .您应该使用qsort()的 output 进行检查。
Fill 2 arrays with this loop用这个循环填充 2 个 arrays

int A[NUM], B[NUM], i, n;

for(i=0;i<NUM;i++){
    n = rand()%99999*rand()%99999;
    A[i] = B[i] = n;
}

Then define a compare function, like this:然后定义一个比较function,像这样:

int cmpfunc (const void * a, const void * b) {
   return ( *(int*)a - *(int*)b );
}

And use it to call qsort() from the standard library and sort B并使用它从标准库中调用qsort()并对 B 进行排序

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

The last step will be to compare A and B for a good number of random generated arrays.最后一步是比较 A 和 B 以获得大量随机生成的 arrays。 If they're equal, your implementation works.如果它们相等,则您的实现有效。
Of course this is not mathematical proof, but if you're working on Selection sort, you'll be fine with empirical testing当然这不是数学证明,但是如果您正在使用选择排序,那么您可以进行经验测试

Yes in this particular case your function is correct but in general there are at least three more or less serious drawbacks in the function.是的,在这种特殊情况下,您的 function 是正确的,但总的来说,function 至少存在三个或多或少的严重缺陷。

The first one is that the function depends on the magic number NUM .第一个是 function 取决于幻数NUM So you can not use the function with any array with a different number of elements.因此,您不能将 function 与具有不同元素数量的任何数组一起使用。

The second one is that you should not swap elements of the array with equal values.第二个是您不应该交换具有相等值的数组元素。 That is instead of this condition那是代替这个条件

if(k >= A[j]){

You should use the following condition您应该使用以下条件

if(k > A[j]){

The third one is that you can not use the function to sort an array in the descending order or using some other criteria of sorting.第三个是您不能使用 function 对数组进行降序排序或使用其他一些排序标准。

At least your function should not depend on a magic number.至少您的 function 不应依赖于幻数。

For integer arrays I would declare and define the function the following way.对于 integer arrays 我将通过以下方式声明和定义 function。

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

void selection_sort( int a[], size_t n, int cmp( const void *, const void * ) )
{
    for ( size_t i = 0; i < n; i++ )
    {
        size_t pos = i;
        
        for ( size_t j = i + 1; j < n; j++ )
        {
            if ( cmp( a + j, a + pos ) < 0 )
            {
                pos = j;
            }
        }
        
        if ( pos != i )
        {
            int tmp = a[i];
            a[i] = a[pos];
            a[pos] = tmp;
        }
    }
}

int ascending_order( const void *p1, const void *p2 )
{
    int a = *( int * )p1;
    int b = *( int * )p2;
    
    return ( b < a ) - ( a < b );
}

int descending_order( const void *p1, const void *p2 )
{
    int a = *( int * )p1;
    int b = *( int * )p2;
    
    return ( a < b ) - ( b < a );
}

int main(void) 
{
    enum { N = 20 };
    int a[N];
    
    srand( ( unsigned int )time( NULL ) );
    
    for ( size_t i = 0; i < N; i++ )
    {
        a[i] = rand() % N;
    }
    
    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
    
    selection_sort( a, N, ascending_order );
    
    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
    
    selection_sort( a, N, descending_order );
    
    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
    
    return 0;
}

The program output might look like程序 output 可能看起来像

2 10 1 2 14 8 0 17 13 11 5 12 9 3 13 13 3 12 4 1 
0 1 1 2 2 3 3 4 5 8 9 10 11 12 12 13 13 13 14 17 
17 14 13 13 13 12 12 11 10 9 8 5 4 3 3 2 2 1 1 0 

The function can be written in a more general form when it can be applied to an array of any type similarly to the standard C function qsort .当 function 可以应用于任何类型的数组时,它可以写成更通用的形式,类似于标准 C function qsort But it is a more complicated task.但这是一项更复杂的任务。

As L.Grozinger already commented , two algorithms having the same complexity does not mean that they will be equally fast.正如 L.Grozinger 已经评论的那样,具有相同复杂性的两种算法并不意味着它们会同样快。 It only means that if you scale the input by some factor, the running time of both algorithms will increase by the same proportion.这只意味着如果你按某个因子缩放输入,两种算法的运行时间都会以相同的比例增加。

For example, suppose that you first run both bubbleSort and selectionSort on an input of 100 elements.例如,假设您首先对 100 个元素的输入同时运行 bubbleSort 和 selectionSort。 You might, for example, find that bubbleSort takes 4 milliseconds while selectionSort needs only 3 milliseconds.例如,您可能会发现 bubbleSort 需要 4 毫秒,而 selectionSort 只需要 3 毫秒。 If you now scale the input by a factor two, ie, to 200 elements, you'll find that both algorithms take about four times as long: the running time of bubbleSort jumps from 4 ms to 16 ms, while the running time of selectionSort jumps from 3 to 12 ms.如果您现在将输入缩放两倍,即到 200 个元素,您会发现两种算法的运行时间大约是原来的四倍:bubbleSort 的运行时间从 4 毫秒跳到 16 毫秒,而 selectionSort 的运行时间从 3 毫秒跳到 12 毫秒。

BubbleSort is actually known to be slower than selectionSort. BubbleSort 实际上比 selectionSort 慢。 To see why this is the case, consider that comparison sorting algorithms (a family that bubbleSort and selectionSort are both members of) need to do two kinds of things: comparing and swapping.要了解为什么会出现这种情况,请考虑比较排序算法(bubbleSort 和 selectionSort 都是其中的成员)需要做两种事情:比较和交换。 Both algorithms need to perform O(N^2) comparisons in order to sort a list, which is why both have an overall complexity of O(N^2).两种算法都需要执行 O(N^2) 比较才能对列表进行排序,这就是为什么两者的总体复杂度都是 O(N^2)。 But selectionSort needs only O(N) swaps, where bubbleSort needs O(N^2) swaps.但是 selectionSort 只需要 O(N) 次交换,而 bubbleSort 需要 O(N^2) 次交换。 The big O notation normally hides this fact, because it abstracts away details about particular operations.大 O 表示法通常隐藏了这一事实,因为它抽象出了有关特定操作的细节。

A similar thing is going on with quickSort and heapSort. quickSort 和 heapSort 也发生了类似的事情。 They are both O(n log n), but heapSort makes way more cache misses than quickSort.它们都是 O(n log n),但是 heapSort 比 quickSort 产生更多的缓存未命中。 That's why quickSort is much, ahem, quicker .这就是为什么 quickSort更快,咳咳。

BubbleSort serves only an educational purpose; BubbleSort 仅用于教育目的; it is in all respects worse than both insertionSort and selectionSort.它在各方面都比 insertSort 和 selectionSort 差。 In fact, this is the reason why it serves an educational purpose.事实上,这就是它服务于教育目的的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的计数器在这个 Python 3 排序和计数实现中不起作用? - Why is my counter not working in this Python 3 sort and count implementation? 为什么我的string_split实现不起作用? - Why does my string_split implementation not work? 为什么我的堆栈实现中的 `push()` 无法正常工作? - Why `push()` in my stack implementation isn't working correctly? 为什么我的二进制搜索实现找不到最后一个元素? - Why doesn't my binary search implementation find the last element? 为什么我的MinArray实现不回收未使用的ID? - Why doesn't my MinArray implementation recycle unused ids? 为什么我在Swift中的array.sorted(by:)实现返回一个奇怪的顺序? - Why is my implementation of array.sorted( by: ) in Swift returning a strange order? 为什么我的动态字符串数组实现泄漏? - Why does my implementation of a dynamic string array leak? 为什么这个普通数组实现比std :: vector实现性能慢? - Why is this plain array implementation slower than the std::vector implementation performance? 为什么我的递归比Array.exists更快? - Why is my recursion faster than Array.exists? 我的函数实现有什么问题吗? - is there anything wrong with my function implementation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM