【问题标题】:Why is the length usually calculated this way for BubbleSort algorithm?为什么冒泡排序算法通常以这种方式计算长度?
【发布时间】:2019-11-10 14:51:56
【问题描述】:

所以我只是想了解气泡排序(当我看到这种东西时,它可能对我使用其他算法有帮助)如何与嵌套的 for 循环一起工作。

我注意到大多数人会这样循环:

public static void BubbleSort(int[] arr, int arr_size)
{
    int i, j, temp;
    bool swapped;
    for (i = 0; i < arr_size - 1; i++)
    {
        swapped = false;
        for (j = 0; j < arr_size - i -1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                swapped = true;
            }
        }
        if (swapped == false)
        {
            break;
        }
    }            
}

我是这样做的(只是略有不同;注意嵌套循环大小检查:

public static void BubbleSort(int[] arr, int arr_size)
{
    int i, j, temp;
    bool swapped;
    for (i = 0; i < arr_size - 1; i++)
    {
        swapped = false;
        for (j = 0; j < arr_size - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                swapped = true;
            }
        }
        if (swapped == false)
        {
            break;
        }
    }            
}

它似乎适用于我迄今为止所做的每一次检查。

我想总结一下,我想知道为什么第一个循环的大小是 - 1(我知道这是因为末尾有空格)而嵌套循环的大小是 - i - 1(在至少我见过很多)。感谢您的任何反馈!

【问题讨论】:

  • 您的循环是正确代码的超集。当然,它会工作,但它会在 N^2 时间而不是 N log(N) 时间内运行。因为你检查的项目更多
  • @Emad 这不是 O(N log(N)),它只是 O(N^2/2),仍然是 O(N^2)。它恰好减少了大约一半的步骤。
  • 扩展@Emad 的回答:一旦一个项目被分类到位,它就不会再移动——因此没有必要检查它。您的循环检查并重新检查已排序的项目。
  • en.wikipedia.org/wiki/Bubble_sort 查看最坏情况与通常情况的不同之处。最坏的情况并不总是发生。在您的代码中总是如此。
  • 啊,好吧,我想我现在明白了!感谢您的反馈

标签: c# bubble-sort


【解决方案1】:

内循环的效果:

for (j = 0; j < arr_size - i - 1; j++)
{
    if (arr[j] > arr[j + 1])
    {
        temp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = temp;
        swapped = true;
    }
}

正在查找数组中的最大元素并将其放置到最后一个位置。因此,对于i == 0(外部循环的索引),它将其移动到最后一个数组位置。对于i == 1,数组的整体最大元素已经在最后一个数组位置,因此不需要再次处理。对于i == 2 等,情况是一样的。换句话说,数组是从“向后”通过“冒泡”(因此算法的名称)每次迭代的最大元素进行排序的。

Wikipedia 上有一个很好的分步示例。

在您的第二个示例中,通过在 for 循环子句中省略 - i,您只是在不必要地检查先前(外循环)迭代中已经存在的数组元素,因此无法再更改。

【讨论】:

  • 这个答案正是我一直在寻找的。非常感谢您抽出宝贵的时间!
猜你喜欢
  • 2021-10-03
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 2013-09-04
  • 2013-11-02
  • 1970-01-01
相关资源
最近更新 更多