【问题标题】:Simple Selection Sort program. Works flawlessly 85% of times but sometimes doesn't sort简单的选择排序程序。 85% 的时间都可以完美运行,但有时无法排序
【发布时间】:2021-04-08 18:03:56
【问题描述】:
#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;
    }

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

    // Sorting the array
    for (outer = 0; outer < 9; outer++) {
        didSwap = 0;

        for (inner = outer + 1; inner < 10; inner++) {
            if (nums[inner] < nums[outer]) {
                temp = nums[inner];
                nums[inner] = nums[outer];
                nums[outer] = temp;
                didSwap = 1;
            }
        }

        if (didSwap == 0) {
            break;
        }
    }

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

    printf("\n");

    return 0;
}

它在大多数情况下都能正常工作,但有时无法正确排序,有时根本无法排序。

附:如果代码不正确,那么为什么它在 85% 的情况下都能正常工作。

错误快照

【问题讨论】:

  • 找到一个不起作用的特定情况,尝试最小化输入集,然后使用调试器在监视变量和语句的同时逐语句执行代码他们的价值观。
  • 这是相同的code you posted 2 days ago。这个问题有什么不同?
  • @Blastfurnace 啊是的你是对的
  • 希望我的回答能回答您关于有时不排序的问题,但无论如何,像您那样复制问题不是正确的方法。请选择具有您喜欢的答案的问题并删除另一个问题,如果您不尽快,我们会这样做并且可能不是您喜欢的方式,包括删除您的两个问题...

标签: c sorting selection-sort


【解决方案1】:

您的代码是冒泡排序的错误实现。

如果数组的第一个元素是较小的元素,例如您问题中的代码

if (didSwap == 0) {
    break;
}

在第一回合中断循环,没有任何东西是排序的。

冒泡排序中存在类似于didSwap的测试,但实现方式不同,它不做if (nums[inner] &lt; nums[outer])而是将每个元素与next.

如果代码不正确,那么为什么它在 85% 的情况下都能正常工作

我不知道这 85% 来自哪里(而且很可能是错误的),当然这一切都取决于数组中的值,但是当 nums[outer] 小于所有具有更大索引的元素时,您的程序停止,并且具有更大索引的元素不被排序。在您问题的示例中,第一个元素是数组中较小的元素,因此根本没有排序。


所以有两种可能:

  • 删除所有有关 didSwap

  • 实现冒泡排序

让冒泡排序修改你的内部循环,例如:

for (inner = outer + 1; inner < 8; inner++) {
    if (nums[inner] > nums[inner + 1]) {
        temp = nums[inner];
        nums[inner] = nums[inner + 1];
        nums[inner + 1] = temp;
        didSwap = 1;
    }
}

例如使用您在问题中给出的值:

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

int main()
{
    int ctr, inner, outer, didSwap, temp;
#if 1
    int nums[10] = { 4, 6, 25, 9, 60, 59, 44, 65, 59, 90};
#else
    int nums[10];
    time_t t;

    srand(time(&t));

    for (ctr = 0; ctr < 10; ctr++) {
        nums[ctr] = (rand() % 99) + 1;
    }
#endif

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

    // Sorting the array
    for (outer = 0; outer < 9; outer++) {
        didSwap = 0;

        for (inner = outer + 1; inner < 8; inner++) {
            if (nums[inner] > nums[inner + 1]) {
                temp = nums[inner];
                nums[inner] = nums[inner + 1];
                nums[inner + 1] = temp;
                didSwap = 1;
            }
        }

        if (didSwap == 0) {
            break;
        }
    }

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

    putchar('\n');

    return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ ./a.out

Here is the list before the sort:
  4  6 25  9 60 59 44 65 59 90

Here is the list after sorting:
  4  6  9 25 44 59 59 60 65 90
pi@raspberrypi:/tmp $ 

【讨论】:

  • 首先,didSwap 标志变量在 for 循环之外,因此只有在没有排序的情况下测试整个步骤而不只是第一个元素时,该条件才会变为真。其次,对于您的“很可能是错误的”评论,只要尝试运行我的代码,您就会知道!!!!
  • @jiVatx19 当然 var 是在嵌套循环中定义并设置为 0 的,显然你不明白会发生什么。我也鼓励你不要对帮助你的人咄咄逼人
  • 也是一种选择排序算法,而不是冒泡排序算法。这是一个不同的问题。
  • 我无意变得咄咄逼人,如果我听起来如此,那么对不起。请运行我的代码一次。
  • @jiVatx19 因此,删除您的两个克隆问题之一,然后“接受”您对仍然存在的问题的首选答案,点击左侧的灰色标记(V 类型)以表示您的问题已结束(What should I do when someone answers my question?
【解决方案2】:

由于某种原因,您 break 如果没有对任何特定元素进行交换,从而使其他元素未排序:

if (didSwap == 0) {
    break;
}

您需要删除上述条件以使其正常工作并对所有元素进行排序。在标准的选择排序算法中也不需要这样的条件。

【讨论】:

  • 伙计,didSwap 标志变量在 for 循环之外,因此只有在没有排序的情况下测试整个步骤而不只是第一个元素时,该条件才会变为真。只需尝试运行我的代码,然后告诉我为什么它可以工作 85% 的时间?
【解决方案3】:

当没有交换时,您正在打破外循环。这将不起作用,因此请删除 didSwap 并删除以下代码

if (didSwap == 0) {
    break;
}

程序应该可以正常运行。

【讨论】:

  • 伙计,didSwap 标志变量在 for 循环之外,因此只有在没有排序的情况下测试整个步骤而不只是第一个元素时,该条件才会变为真。只需尝试运行我的代码,然后告诉我为什么它可以工作 85% 的时间?
  • 如果你的第一个元素是最小的,那么它将在一个内部迭代中与所有其他 n-1 个元素进行比较并且没有交换,所以当它从内部循环出来时它甚至不考虑其他元素是否排序,它只是打破了外循环。
  • 谢谢。我明白了。
猜你喜欢
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
相关资源
最近更新 更多