简体   繁体   English

冒泡 Function 在整数数组的 C 中排序

[英]Bubble Function sorting in C on an array of integers

I have coded out a Bubble Function that is supposed to Bubble sort an array of user input integers, but for some reason, my array is only working with arrays with size 6... otherwise the array outputs a zero for the largest number.我已经编写了一个 Bubble Function,它应该对用户输入整数数组进行冒泡排序,但由于某种原因,我的数组仅适用于大小为 6 的 arrays ......否则数组输出最大数字为零。 Please run this code and help me identify the problem.请运行此代码并帮助我找出问题所在。

        #include <stdio.h>
        //prototype
        void bubble(int array[], int size);



        int main(void) 
        {
            int n,i,j,size,temp,counter = 0;
            //FOR SOME REASON, ONLY INPUT SIZE 6 WORKS PERFECTLY.
            int k;
            printf("How many numbers to sort?\n");
            scanf("%d",&size);
            int array[size];
            for(i=0;i<size;i++)
            {
                printf("Enter number %d\n",i+1);
                scanf("%d",&k);
                array[i] = k;
            }
            printf("Array before sorting:\n");

            for(i=0;i<size;i++)
            {
                printf("%d  ",array[i]);
            }

            bubble(array,size);

        return 0;
        }

        // use this if you want to test print an array
        // for(i=0;i<size;i++)
            // {
            //     printf("%d",array[i]);
            // }
        void bubble(int array[], int size)
        {
            int i, j, temp;
            for(j=0;j<size;j++)
            {  
                printf("\nIteration# %d\n",j+1);
                for(i=0;i<size;i++)
                {
                    if(array[i] > array[i+1])
                    {
                        temp = array[i];
                        array[i] = array[i+1];
                        array[i+1] = temp;
                    }
                    printf("%4d",array[i]);

                }

            }
        }

        // void select(int array[], int size)
        // {
        //     int i, j, temp;
        //     min = array[0];
        //     for(j=0;j<size;j++)
        //     {
        //         if(array[j] < min)
        //         {
        //             array[j] = temp;
        //             min = array[j];



        //         }


        //     }

        // }

i<size in combination with i+1 will go past the bounds of the array. i<sizei+1结合将 go 超出数组的边界。

You should replace this:你应该替换这个:

for(i=0;i<size;i++)

with this:有了这个:

for(i=0;i<size-1;i++)

Your inner-loop top-end conditional break is size , but within the loop you reference array[i+1] , which means you're referring to array[size] .您的内循环顶端条件中断是size ,但在循环中您引用array[i+1] ,这意味着您指的是array[size] Since C arrays are zero-base indexed, the only allowable indexing is from 0...(size-1).由于 C arrays 是零基索引,因此唯一允许的索引是从 0...(size-1)。 Your code breaches that by one item repeatedly.您的代码反复违反了一项。

Changing the top-end of the inner loop to size-1 will work in your case.将内部循环的顶端更改为size-1将适用于您的情况。 but there is arguably a better alternative that alleviates you from remembering the minus-1 in the first place.但可以说有一个更好的选择可以让你从一开始就记住负1。 It involves modifying size as you sort to control the top-end of your inner loop directly.它涉及在排序时修改size以直接控制内部循环的顶端。 It also eliminates one local variable that you no longer need).它还消除了一个您不再需要的局部变量)。

    void bubble(int array[], int size)
    {
        while (size-- > 0)
        {  
            for(int i=0; i<size; ++i)
            {
                if(array[i] > array[i+1])
                {
                    int temp = array[i];
                    array[i] = array[i+1];
                    array[i+1] = temp;
                }
            }
        }
    }

Often called a "goes-down-to" expression (because it looks like a long arrow pointing at a limiting value), the outer loop has been changed to become while (size-- > 0) .通常称为“goes-down-to”表达式(因为它看起来像一个指向限制值的长箭头),外部循环已更改为while (size-- > 0) This takes the current value of size to a temporary, decrements size, and compares the temporary against > 0 (more or less).这将size的当前值设为临时值,递减 size,并将临时值与> 0 (或多或少)进行比较。 The result is size now reflects the top limit of your inner loop that you want.结果是size现在反映了您想要的内部循环的上限。 Each enumeration of the outer loop will shrink the next inner loop pass by one.外循环的每个枚举都会将下一个内循环缩小一个。 The point of bubble sort is that, once an element has been "bubbled up" to its proper position, you need not visit that element ever again, something your code is not taking advantage of.冒泡排序的要点是,一旦一个元素“冒泡”到其正确的 position,您就无需再次访问该元素,这是您的代码没有利用的。


Bonus Optimization奖金优化

Finally, you can optimize this further and give your bubblesort the one and only redeeming quality the algorithm can offer: O(n) in best case where the sequence is already sorted.最后,您可以进一步优化这一点,并为您的冒泡排序提供算法可以提供的唯一可取之处:在序列已经排序的最佳情况下为 O(n)。 You do this by doing "swap-detection".您可以通过“交换检测”来做到这一点。 If you ever pass over the inner loop without making a single swap, it makes no sense to perform anymore sorting.如果您在没有进行单次交换的情况下通过了内部循环,那么再执行排序就没有意义了。 The sequence is sorted and you're done.序列已排序,您就完成了。 It's a near-freebie addition to the original algorithm above, and looks like this:这是对上述原始算法的近乎免费的补充,如下所示:

void bubble(int array[], int size)
{
    int swapped = 1;
    while (swapped && size-- > 0)
    {  
        swapped = 0;
        for(int i=0; i<size; ++i)
        {
            if(array[i] > array[i+1])
            {
                int temp = array[i];
                array[i] = array[i+1];
                array[i+1] = temp;
                swapped = 1;
            }
        }
    }
}

Given an already sorted sequence of a ten, a hundred, or a hundred-thousand elements, this will finish after only one pass.给定一个已排序的十个、一百个或十万个元素的序列,这将在一次通过后完成。 Worth noting: even one element out of position on one extreme end will make this optimization irrelevant.值得注意的是:即使是 position 中的一个元素,也会使这种优化变得无关紧要。 Ie if any element that belongs near the beginning is originally near the end, it will take up to size iterations to bring it home, and with that the optimization becomes moot.即,如果任何靠近开头的元素最初靠近结尾,则需要进行一定size的迭代才能将其带回家,这样优化就变得没有意义了。 In short, this sequence简而言之,这个序列

1 3 4 5... 9998 9999 2

will completely foil the optimization above.将完全挫败上述优化。 There are techniques to combat this as well including a two pass inner loop enumeration, where you ascend to bubble up larger values, then reverse direction to descend , bubbling down smaller values.也有一些技术可以解决这个问题,包括两遍内循环枚举,您可以在其中提升以冒泡较大的值,然后反转方向以向下冒泡,将较小的值冒泡。 but at this point you're better off using a finer algorithm like quicksort or heapsort.但此时你最好使用更精细的算法,如快速排序或堆排序。 The discussion of that, and indeed the latter half of this post, is beyond the scope of your question.对此的讨论,实际上是这篇文章的后半部分,超出了您问题的 scope 范围。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM