了解这种基于C的冒泡排序

时间:2013-11-06 00:49:11

标签: c bubble-sort

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

main()
{
    int ctr, inner, outer, didSwap, temp;
    int nums[10];
    time_t t;

    srand(time(&t));

    for (ctr = 0; ctr < 10; ctr++)
    {
        nums[ctr] = (rand() % 99) + 1;
    } 
    puts("\nHere is the list before the sort:"); for (ctr=0; ctr < 10; ctr++) {
    printf("%d\n", nums[ctr]); }

    for(outer = 0; outer < 9; outer++) {
        didSwap = 0;
        for (inner = outer; inner < 10; inner++)
        {
            if (nums[inner] < nums[outer])
            {
               temp = nums[inner];
               nums[inner] = nums[outer];
               nums[outer] = temp;
               didSwap = 1;
            }
        }
        if (didSwap == 0)
        {
            break;
        }
    }
    puts("\nHere is the list after the sort:"); for(ctr = 0; ctr < 10; ctr++) {
    printf("%d\n", nums[ctr]);

    } 
    return 0; 
}

我不明白这一部分:

for(outer = 0; outer < 9; outer++) {
    didSwap = 0;
    for (inner = outer; inner < 10; inner++) {
        if (nums[inner] < nums[outer])
        ...
    }
}

如果outer = 0inner = outer,则innerouter都等于0.如果循环FOR说if (nums[inner] < nums[outer]) 因为内部和外部= 0,nums [0]如何能小于nums [0]?请帮我理解。


我认为我的教科书代码有问题。你觉得怎么样?

现在问题在于 BREAK 。你觉得它在正确的地方吗?

  

if(didSwap == 0){       打破; }

现在问题是如果前两个数组值按升序排列并且 NUMS [] 元素的其余部分是随机的,那么在内部循环的第一次迭代之后它将打破外部循环,因为 didSwap 仍然相当于零。

我试图像这样手动初始化 NUMS [] ..

  

int nums [10] = {4,6,8,65,47,74,21,22,65,36};

请看一下......谢谢

2 个答案:

答案 0 :(得分:3)

1)

这是伪代码,可以帮助您理解:

FOR J=1 TO N-1 {
    FOR I=1 TO N-J { 
        IF A[I]>A[I+1] THEN SWAP A[I],A[I+1]
        NEXT I
    }
    NEXT J
}

2)

至于正在进行冒泡排序 ..这是一个简单的例子:

1) At first we compare the first two elements.
     If the 1st el. is bigger (or equal) than the next el. - we swap them.
     If the 1st el. is smaller -  we do nothing. 
     (The  smallest elements will be closer to the top & biggets to the bottom)
   Then we compare 2nd and 3rd elements, them 3rd and 4th etc. 
   Compare all the elements until the last in array.
   /* In this cycle, the biggest element will go to the bottom. */

2) Then we "forget" the last (the biggest) element and repeat the same again.

3) Repeat 1) and 2) successively until the end. 
   /* After all, all the elements will be sorted now: */
   /* from the smallest to the largest.               */



EXAMPLE:
Suppose we have 4 elements: 8, 6, 2, 1. That's how we will sort them:

1st cycle:
  8, 6, 2, 1
  v  v
   8 is bigger than 6, so we swap them      

  6, 8, 2, 1
     v  v
     8 is bigger than 2, so we swap them      

  6, 2, 8, 1
        v  v
        8 is bigger than 1, so we swap them      

  6, 2, 1, 8 
           v 
          The biggest element is at the bottom now.

2nd cycle:
  6, 2, 1, 8 
  v  v
  6 is bigger than 2, so we swap them      

  2, 6, 1, 8 
     v  v
     6 is bigger than 1, so we swap them      

  2, 1, 6, 8 
        v  v
        6 will always be smaller or equal to 8, so we use ...
        for (inner = 0; inner < (N-outer); inner++)
                                 ^^^^^^^ ... this expression to avoid
                                                  unnecessary actions.

3rd cycle: 
  2, 1, 6, 8     
  v  v
  2 is bigger than 1, so we swap them      

The are 4 elements but we do (4-1)= 3 cycles:
    for(outer = 0; outer < (N-1); outer++)
                            ^^^

3)

现在,假设N = 10outer = Jinner = I

for(J = 0; J < (N-1) ; J++) {
    didSwap = 0;
    for (I = 0; I < (N-J); I++)
    {
        if (nums[I] < nums[I + 1])// at the beginning, here J = 0 and I = 1;
        {                         // then J = 0 and I = 2 etc.
           temp = nums[I];        // It compares the first element with the
           nums[I] = nums[I + 1]; // othe ones and swaps them so more lightweight
           nums[I + 1] = temp;    // (smaller, light) element will move higher.
           didSwap = 1;           // Just like a bubble.
        }
    }
    if (didSwap == 0)
    {
        break;
    }
}

UPDATE:

4)

在完成之前,您无法break排序循环!

查看以下代码。它确实适合冒泡排序伪代码(在这个答案的顶部):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10   // Here you can change the number of elements that
               // will be sorted.

int main()
{
    int ctr, inner, outer, didSwap, temp;
    int nums[N];
    time_t t;

    srand(time(&t));

    for (ctr = 0; ctr < N; ctr++)
    {
        nums[ctr] = (rand() % 99) + 1;  // Filling the elements with random 
    }                                   // values from 1 to 99.

    puts("\nHere is the list before the sort:");
    for (ctr=0; ctr < N; ctr++) {
        printf("%d\n", nums[ctr]);
    }

    didSwap = 0;
    for(outer = 0; outer < (N-1); outer++) {

        for (inner = 0; inner < (N-outer); inner++)
        {
            if (nums[inner] >= nums[inner + 1]) // notice that there is `>=` 
            {                                   // instead of `>`. 
               temp = nums[inner];              // This will exchange also
               nums[inner] = nums[inner + 1];   // equal elements so the
               nums[inner + 1] = temp;          // sorting will work correctly.

            }
        }
        didSwap = 1; // Change `didSwap` only once --> after all cycles
                     // and all swappings: changing it's value after each
                     // swapping is a waste of machine's resources.
    }                    

    /* I can't understand why do you want to use this variable, but here it is. */
    printf(" >>> didSwap = %d <<<\n", didSwap);  

    puts("\nHere is the list after the sort:");
    for(ctr = 0; ctr < N; ctr++) {
        printf("%d\n", nums[ctr]);
    }

    return 0;
}

答案 1 :(得分:0)

你是正确的,在内循环的第一次迭代中,if条件总是为假。

效率低下,但不会使算法不正确。

这会更好:

for (inner = outer+1; inner < 10; inner++)