代码之家  ›  专栏  ›  技术社区  ›  tklustig

使用BubbleSort排序数组失败

c c#
  •  -3
  • tklustig  · 技术社区  · 7 年前

    下面的算法在C中运行得很好#

        public int[] Sortieren(int[] array, int decide)
        {
            bool sorted;
            int temp;
            for (int i = 0; i < array.Length; i++)
            {
                do
                {
                    sorted= true;
                    for (int j = 0; j < array.Length - 1; j++)
                    {
                        if (decide == 1)
                        {
                            if (array[j] < array[j + 1])
                            {
                                temp = array[j];
                                array[j] = array[j + 1];
                                array[j + 1] = temp;
                                sorted= false;
                            }
                        }else if (decide == 0)
                        {
                            if (array[j] > array[j + 1])
                            {
                                temp = array[j];
                                array[j] = array[j + 1];
                                array[j + 1] = temp;
                                sorted= false;
                            }
                        }
                        else
                        {
                            Console.WriteLine("Incorrect sorting parameter!");
                            break;
                        }
                    }
                } while (!sorted);
            }
            return array;
        }
    

    C中的相同操作失败。我只得到要排序的数组的前两个数字。其余数字相同。因此,这段代码似乎也改变了数组,而不仅仅是对其进行排序。有什么想法吗,bug在哪里?

    #include <stdio.h>
    #include<stdbool.h>
    #define MAX 10
    
    void main(void)
    {
       int random_numbers[MAX],temp,Array_length;
       bool sorted;
       srand(time(NULL));
       for(int i=0;i<=MAX;i++){
            random_numbers[i]=rand()%1000;
       }
       Array_length=sizeof(random_numbers) / sizeof(int);
       printf("List of (unsorted) numbers:\n");
       for(int i=0;i<MAX;i++){
            if(i==MAX-1)
                printf("%i",random_numbers[i]);
            else
                printf("%i,",random_numbers[i]);
       }
       //Searching algorithm
       for(int i=0;i<Array_length;i++){
        do{
           sorted=true;
           for(int j=0;j<Array_length-1;j++){
            if(random_numbers[j]>random_numbers[j+1]){
                temp=random_numbers[j];
                random_numbers[j]==random_numbers[j+1];
                random_numbers[j+1]=temp;
                sorted=false;
            }
           }
        }while(!sorted);
       }
       printf("\n");
       for(int i=0;i<Array_length;i++){
            if(i==Array_length-1)
                printf("%i",random_numbers[i]);
            else
                printf("%i,",random_numbers[i]);
       }
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Jose Fernando Lopez Fernandez    7 年前

    交换算法中有错误:

    if (zufallszahlen[j] > zufallszahlen[j+1]) {
        temp = zufallszahlen[j];
        zufallszahlen[j] == zufallszahlen[j+1]; // here
        zufallszahlen[j+1] = temp;
        sortiert = false;
    }
    

    在指定给之后的行中 temp ,您的双等号将导致检查相等,而不是赋值。这仍然是法律法规( == 是一个运算符,使用它们的and表达式将计算为某物),表达式将根据语句的真值计算为1或0。请注意,即使您没有使用表达式,这也是合法的,通常情况下,布尔值可能会用于控制流。

    请注意,其他操作符也是如此。例如 = 运算符将右侧的值赋给左侧的变量,因此假设出现如下错误 if (x = 0) 将意味着永远不会调用此分支,因为 x = 0 每次都将计算为false,当您可能打算分支时 x == 0

    另外,为什么要使用布尔值来检查数组是否已排序?冒泡排序是一种简单的算法,因此实现起来应该很简单,而且 the definition of an algorithm ,保证完成和正确。如果您试图为性能目的进行优化,例如根据数据是否已排序在合并排序和插入排序之间进行选择,那么我可以理解,但您正在检查数据是否已排序 在你分类的时候 ,这真的没什么意义,因为算法会告诉你什么时候排序,因为它会完成。添加布尔检查只会增加开销,而不会对您造成任何影响。

    另外,请注意,在C#实现中,您是如何重复排序过程的。 This is a good sign your design is wrong 。您可以接受一个整数以及实际值 int[] 数组,然后使用该整数进行分支。然后,根据我收集的信息,您可以使用 < > ,具体取决于传入的值。我对此感到很困惑,因为两者都可以。你从添加这个功能中一无所获,所以我不明白你为什么要添加它。

    还有,为什么要重复 printf 声明?甚至做 if/else if 我也许能理解。但你正在做 if/else 。这在逻辑上等同于 P V ~P 并将始终评估为 true ,所以你最好把 if 以及 else 只要一个 打印F 陈述

    下面是冒泡排序程序的实现,我想指出一些事情。首先,一般不赞成宣布 main void ( What should main() return in C and C++? )。

    我很快还想指出,尽管我们将数组的最大长度声明为宏,但我显式定义的所有数组函数都采用 size_t referential透明度的size参数。

    最后但并非最不重要的一点,我建议不要在程序/函数开始时声明所有变量。这是一个 more contested topic among developers ,尤其是因为它过去是必需的,因为编译器需要确切地知道需要分配哪些变量。随着编译器越来越好,他们可以接受代码中的变量声明(甚至可以完全优化某些变量),因此一些开发人员建议在需要时声明变量,以便他们的声明有意义(即…你知道你需要它们),还可以减少代码噪音。

    也就是说,一些开发人员更喜欢在程序/函数的开头声明他们的所有变量。您将特别看到:

    int i, j, k;
    

    或者它的一些变体,因为开发人员预先声明了他们所有的循环计数器。同样,我认为这只是代码噪音,在我看来,当你使用C++时,一些语言语法本身就是代码噪音,但请注意这一点。

    例如,与其像这样声明一切:

    int zufallszahlen[MAX], temp, Array_length;
    

    您可以这样声明变量:

    int zufallszahlen[MAX];
    int Array_length = sizeof (zufallszahlen) / sizeof (int);
    

    这个 临时雇员 然后尽可能长时间地推迟变量,这样就可以清楚地知道它在什么时候有用。在我的实现中,您会注意到我声明了它 在里面 交换功能。

    出于教学目的,我还想补充一点,排序整数时不必使用交换变量,因为可以执行以下操作:

    a = a + b;
    b = a - b;
    a = a - b;
    

    然而,我要说的是,我相信临时交换变量会让交换变得更加熟悉,所以我会说把它留在里面,但这是我个人的偏好。

    我确实建议使用 大小\u t 对于 Array_length 然而,因为这是 sizeof 操作员返回。这也是有意义的,因为数组的大小不会为负。

    这是 include 语句和函数。记住,我不包括 <stdbool.h> 因为你所做的布尔检查对算法没有任何作用。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAX 10
    
    void PrintArray(int arr[], size_t n) {
        for (int i = 0; i < n; ++i) {
            printf("%d ", arr[i]);
        }
    
        printf("\n");
    }
    
    void PopulateArray(int arr[], size_t n) {
        for (int i = 0; i < n; ++i) {
            arr[i] = rand() % 1000 + 1;
        }
    }
    
    void BubbleSortArray(int arr[], size_t n) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n - 1; ++j) {
                if (arr[j] > arr[j+1]) {
                    int temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    

    要实现冒泡排序算法,现在唯一要做的就是像之前一样初始化随机数生成器,创建数组并填充它,最后对数组进行排序。

    int main()
    {
        srand(time(NULL));
    
        int arr[MAX];
        size_t array_length = sizeof (arr) / sizeof (int);
    
        PopulateArray(arr, array_length);
        PrintArray(arr, array_length);
        BubbleSortArray(arr, array_length);
        PrintArray(arr, array_length);
    }
    

    我希望这有帮助,如果你有任何问题,请告诉我。