【问题标题】:Why is the first for-loop decrementing?为什么第一个for循环递减?
【发布时间】:2021-07-01 14:24:03
【问题描述】:

当我试图理解冒泡排序的概念时,我偶然发现了这段令我困惑的代码。为什么第一个for循环递减?为什么不是for (int i=0; i<len; i++) {}

void bubblesort(int arr[], int len){
    int k=0; //Tauschvariable
    // Elemente, von rechts beginnend
    for (int i=len; i>0; i--) {
        // Läuft das array nach links ab
        for (int j=0; j<len-1;j++){
            // vergleich zweier
            if(arr[j]>arr[j+1]){
            k = arr[j];
            arr[j+1]=k;
            arr[j] = arr[j+1];
            }
        }
    }
}

【问题讨论】:

  • 这是因为内部循环的每次迭代都会将数组未排序部分的最高元素冒泡到arr[len-1], arr[len-2],...
  • 你为什么不尝试反转它并比较结果?
  • 这段代码不起作用是吗?交换 arr[j]arr[j+1] 的代码对我来说看起来不正确。通常j 循环会从0i-2,而不是每次都到数组的末尾。

标签: c algorithm sorting for-loop bubble-sort


【解决方案1】:

这并不重要,它是双向的。如果您仔细观察,i 不会在其他任何地方使用。我猜作者出于某种原因想要这样做。

【讨论】:

  • 通常j 循环是for (int j = 0; j &lt; i-1; j++)
  • @PaulHankin - 是的,这是一种可能的优化。另一种方法是在迭代时只记下最大的值,最后只执行一次交换。
【解决方案2】:

它只是将最大传递次数限制为数组O(n^2) 的大小通过递减和针对零进行测试一些编译器可能会利用使用的 CPU 架构并使用零标志而不是额外的 cmp 指令如果与0 以外的任何其他值进行比较,则需要。

例如;i&lt;n;i++)可以翻译成:

inc i
cmp i,n
jc ???

;i&gt;0;i--)可以翻译成:

dec i
jnz ???

像往常一样(对于我在此站点上看到的任何冒泡排序),您的冒泡排序实现缺少停止条件,因此一旦对数组进行排序它就不会进行迭代,从而使其非常慢(总是通过n^2 迭代)。

我更习惯于这样的冒泡排序(C++):

template <class T> void sort_asc_bubble(T *a,int n)
    {
    int i,e; T a0,a1;
    for (e=1;e;n--)                                     // loop until no swap occurs
     for (e=0,a0=a[0],a1=a[1],i=1;i<n;a0=a1,i++,a1=a[i])// proces unsorted part of array
      if (a0>a1)                                        // condition if swap needed
      { a[i-1]=a1; a[i]=a0; a1=a0; e=1; }               // swap and allow to process array again
    }
template <class T> void sort_dsc_bubble(T *a,int n)
    {
    int i,e; T a0,a1;
    for (e=1;e;n--)                                     // loop until no swap occurs
     for (e=0,a0=a[0],a1=a[1],i=1;i<n;a0=a1,i++,a1=a[i])// proces unsorted part of array
      if (a0<a1)                                        // condition if swap needed
      { a[i-1]=a1; a[i]=a0; a1=a0; e=1; }               // swap and allow to process array again
    }

对不起,它在 C++ 中,但如果你摆脱模板并将 T 与使用的数据类型交换,你会再次得到 C。像这样的东西(只是在答案编辑器中重写,因此未经测试):

#define T int
void sort_asc_bubble(T *a,int n)
    {
    int i,e; T a0,a1;
    for (e=1;e;n--)                                     // loop until no swap occurs
     for (e=0,a0=a[0],a1=a[1],i=1;i<n;a0=a1,i++,a1=a[i])// proces unsorted part of array
      if (a0>a1)                                        // condition if swap needed
      { a[i-1]=a1; a[i]=a0; a1=a0; e=1; }               // swap and allow to process array again
    }
void sort_dsc_bubble(T *a,int n)
    {
    int i,e; T a0,a1;
    for (e=1;e;n--)                                     // loop until no swap occurs
     for (e=0,a0=a[0],a1=a[1],i=1;i<n;a0=a1,i++,a1=a[i])// proces unsorted part of array
      if (a0<a1)                                        // condition if swap needed
      { a[i-1]=a1; a[i]=a0; a1=a0; e=1; }               // swap and allow to process array again
    }

注意e 变量...因此,如果发生任何交换,则为真,如果在嵌套 for 循环完成后为假,则停止...这将使您的冒泡排序平均快得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2019-08-20
    相关资源
    最近更新 更多