使用BubbleSort排序数组失败

时间:2018-04-15 06:55:04

标签: c# c

以下算法在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中的相同事情失败了。我只得到排序的数组的前两个数字。其余数字相同。所以,这段代码似乎也改变了数组,而不是只对其进行排序。任何想法,错误在哪里?

#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 个答案:

答案 0 :(得分:2)

您的交换算法出错:

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

在分配给temp后的行中,您的双等号会导致检查是否相等而不是分配。这仍然是合法代码(==是一个运算符,并且使用它们的表达式求值),并且表达式将根据语句的真值评估为1或0。请注意,即使您没有使用表达式,这也是合法的,通常布尔值可能会用于控制流程。

请注意,其他运营商也是如此。例如,=运算符将右侧的值赋给左侧的变量,因此假设if (x = 0)之类的错误将意味着永远不会调用此分支,因为x = 0将会每当你想要在x == 0时分支时,评估为假。

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

另外,请注意在C#实现中,您重复了排序过程。 This is a good sign your design is wrong。您在C#代码中接受一个整数以及实际的int[]数组,并使用该整数进行分支。然后,从我可以收集的内容中,您可以使用<>进行排序,具体取决于传入的值。我对此非常困惑,因为其中任何一个都可以。你没有从添加这个功能中获得任何好处,所以我很困惑你为什么要添加它。

另外,为什么要重复printf陈述?即使做if/else if我也许会理解。但你正在做if/else。这在逻辑上等同于P V ~P,并且总是会评估为true,因此您也可以删除ifelse,只需要一个printf声明。

下面是您的冒泡排序程序的实现,我想指出一些事情。首先,将main声明为voidWhat should main() return in C and C++?)通常不赞成。

我很快也想指出,即使我们将数组的最大长度声明为宏,我明确定义的所有数组函数都会使用size_t大小参数来进行引用透明。

最后但同样重要的是,我建议不要在程序/函数的开头声明所有变量。这是一个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);

然后尽可能长时间地推迟temp变量,以便它显而易见,并且它是否有用。在我的实现中,你会注意到我在交换函数中声明了它。

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

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

但是,我会说,我相信临时交换变量会使交换变得更加熟悉,所以我会说留下来,但这是我个人的偏好。

但我建议size_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);
}

我希望这会有所帮助,如果您有任何问题,请与我联系。