c# - 使用冒泡排序对数组进行排序失败

标签 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]);
   }
}

最佳答案

交换算法中存在错误:

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每次都会得出false值,当您打算在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语句。

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

我很快也要指出,即使我们将数组的最大长度声明为宏,但我明确定义的所有数组函数都采用size_t 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);


然后,尽可能长地推迟temp变量,以使其在何时和有用时显而易见。在我的实现中,您会注意到我在swap函数中声明了它。

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

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);
}


希望对您有所帮助,如有任何疑问,请与我们联系。

关于c# - 使用冒泡排序对数组进行排序失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49839275/

相关文章:

c# - 类关键字 - 显式指示继承接口(interface)?

c# - 具有非必需参数的 SQL 存储过程

struct proc 中的starttime 与solaris 中的struct psinfo_t 的比较

C到arm汇编代码转换

c++ - 为什么 C++ 中 char 不被视为数字?

c# - 声明基类出错的类

c# - 预期类型 'Value' 上的 'Resource' 是实例成员

c# - List<T> 中使用了哪种算法来动态分配内存?

c - Gasport 或 Shell Sort 无法正确滑动

c - AWS lib3s C/C++ 库示例代码/教程