【问题标题】:Understanding this C-based bubble sort理解这种基于 C 的冒泡排序
【发布时间】:2013-11-06 00:49:10
【问题描述】:
#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 = outerinnerouter 都等于0。如果循环FOR 显示if (nums[inner] &lt; nums[outer]) 那么 nums[0] 怎么能比 nums[0] 小,因为内部和外部都 = 0?请帮我理解。


伙计们,我认为我的教科书代码有问题。你觉得呢?

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

如果 (didSwap == 0) { 休息; }

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

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

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

请看一下...谢谢

【问题讨论】:

  • 我不妨先看看formatting guide,让这个问题更容易阅读。
  • 对不起,我首先不明白如何在这里发布代码。
  • @Arif,嘿,你还需要帮助吗?
  • @JulianKhlevnoy 我在您的个人资料中查找了您的电子邮件地址。但它不在那里。如果你不介意,我还有一些问题。
  • @Arif,我不介意。我的电子邮件在我的答案下方的最后一条评论中。通过电子邮件交谈会更加舒适和轻松。

标签: c bubble-sort


【解决方案1】:

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

【讨论】:

  • 非常感谢...伙计。你能告诉我我发布的代码吗?我也想知道。
  • 在答案号 2 中,为什么在内部循环的第一次迭代中,if 条件将始终为 false....n 有什么更好的地方?
  • 太棒了。现在我认为我的教科书的作者只是让它变得复杂,而且他没有解释他为什么这样做。虽然他是个好作者。非常感谢人
  • 你非常乐于助人。非常感谢。
  • @Arif,注意在这种情况下if (nums[I] &lt; nums[I + 1])(而不是你的if (nums[inner] &lt; nums[outer]))你避免了在每个循环的第一次迭代中不必要的if 2 &lt; 2比较。 Adam 想告诉您,它不会影响程序 - 这只是一个比较。但是您的代码看起来并不完全像冒泡排序。这与它非常相似,但是您正在以另一种方式对 qute 进行排序,尽管这种方式与冒泡排序非常相似。衷心祝愿您未来好运!
【解决方案2】:

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

这样效率低下,但不会导致算法不正确。

这样会更好:

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

【讨论】:

  • @Arif 你是在问冒泡排序是如何工作的,或者为什么那个特定的 if 语句有这个条件?
  • 教科书经常包含错误。在这种情况下,这无关紧要。这只是一个冗余的循环循环。
  • 完全正确。该代码有效,它只是进行了不必要的检查。请注意,@Arif,拥有一个条件为 false 的 if 是完全可以的。
  • @Adam 我想知道他们如何编写这段代码> if (nums[inner]
  • 对于inner == outer(即循环的第一次迭代)if 将是假的并且根本不执行的情况。然后for 循环递增,inner++,下一次if 可能为真。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 2021-06-22
  • 2017-03-19
  • 2014-03-26
  • 2018-11-13
  • 1970-01-01
相关资源
最近更新 更多