1
#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 = 0然后inner = outer两者都inner等于outer0。如果循环FOR说if (nums[inner] < nums[outer]) 那么nums [0]怎么能小于nums [0],因为inner和outer = 0?请帮我理解。


伙计们,我认为我的教科书代码有问题。你怎么看?

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

if (didSwap == 0) { 休息; }

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

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

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

请看看...谢谢

4

2 回答 2

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;
    }
}

更新:

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;
}
于 2013-11-06T01:08:56.403 回答
0

您是正确的,在内部循环的第一次迭代中,该if条件将始终为假。

这是低效的,但它不会使算法不正确。

这会更好:

for (inner = outer+1; inner < 10; inner++)
于 2013-11-06T01:08:35.543 回答