如何在C#中展示步骤的同时对整数数组进行冒泡排序

3

C#视觉工作室 - Windows窗体应用程序

我正在尝试创建一个程序,对一个种子整数数组进行冒泡排序,并逐行显示每个步骤。该程序正是这样做的,但我希望在完全排序后停止写入数组。例如,一个{1, 4, 5, 2, 6}的数组将显示如下:

          1  4  5  2  6
          1  4  2  5  6
          1  2  4  5  6
          1  2  4  5  6
          1  2  4  5  6

我希望它在第三行后停止。这是当前的代码:
    int[] randArray = new int[5];
    private void btnLotto_Click(object sender, EventArgs e) {
        fillArray();
        sortArray();
    }
    private void fillArray() {
        Random random = new Random(int.Parse(txtSeed.Text));
        for (int i = 0; i < randArray.Length; i++) {
            int randomNumber = random.Next(1, 51);
            randArray[i] = randomNumber;
        }
    }
    private void displayArray() {
        for (int i = 0; i < randArray.Length; i++) {
            txtLotto.AppendText(randArray[i].ToString().PadRight(3));
        }
        txtLotto.AppendText("\r\n");
    }
    private void sortArray() {
        txtLotto.Text = "";
        for (int i = 0; i < randArray.Length; i++) {
            for (int j = 0; j < randArray.Length - 1; j++) {
                if (randArray[j] > randArray[j + 1]) {
                    swap(ref randArray[j], ref randArray[j + 1]);
                }
            }
                displayArray();
        }
    }
    private void swap(ref int a, ref int b) {
        int tempA = a;
        a = b;
        b = tempA;
    }

这看起来像是一个学生练习,我说的对吗?在你的sortArray()函数中,第一个for循环应该测试数组是否已经排序过,并在这种情况下执行一个break - Vyrira
Vyrira,是的,这是一个学生练习。我不确定如何测试它是否已经排序。 - Tyler Arnett
2
如果它不像这个链接中的内容一样酷,我会感到失望。 - itsme86
@TylerArnett - 你可以通过将每个数字与其相邻的数字进行比较来测试它是否已经排序;如果相邻的数字更小,则它还没有排序。 - Adam V
2个回答

4
如果您只想在每次运行外部循环时显示一次,但又不想在没有更改时显示,则可以设置一个标志,并在适当时才显示。
bool swapped = false;
for (int i = 0; i < randArray.Length; i++) {
    for (int j = 0; j < randArray.Length - 1; j++) {
        if (randArray[j] > randArray[j + 1]) {
            swap(ref randArray[j], ref randArray[j + 1]);
            swapped = true;
        }
    }
    if (swapped) {
        displayArray();
    }
}

翻译结果:

我会修改代码,使其在交换后立即进行显示:

for (int i = 0; i < randArray.Length; i++) {
    for (int j = 0; j < randArray.Length - 1; j++) {
        if (randArray[j] > randArray[j + 1]) {
            swap(ref randArray[j], ref randArray[j + 1]);
            displayArray(); // Moved from outer for loop
        }
    }
}

这样只有在发生交换时才会重新显示。


Adam V,现在代码不再重复最后一行,但需要超过5个步骤才能完成。它不再按顺序完全冒泡排序。例如,数组{31, 39, 41, 28, 11}排序需要8步,因为每次循环只进行1次交换。它不会先将41与28交换,然后再与11交换。这需要2个步骤来完成。 - Tyler Arnett
@TylerArnett 不太确定你的意思。这将在每次排序后显示新数组。如果您想查看“第一行”(即未排序的列表),只需在 sortArray() 之前调用 displayArray()。此答案不会改变排序的行为。 - Rob

1

在内部排序循环中,您需要存储是否进行了任何交换。如果您没有进行任何更改,则列表已排序并且可以退出。

displayArray();
for (int i = 0; i < randArray.Length; i++) {
        bool changed=false;
        for (int j = 0; j < randArray.Length - 1; j++) {
            if (randArray[j] > randArray[j + 1]) {
                swap(ref randArray[j], ref randArray[j + 1]);
                changed=true;
            }
        }            
        if(changed)
            displayArray();
        else
            break;
    }

什么都没变?那很奇怪,因为我刚刚测试的时候,最后一行显示了两次。除此之外,一切都是想要的。 - Samuel Wrååk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接