使用结构成员时的冒泡排序

Bubble sort when using struct members

struct SSales
    {
        private int Y;
        private double S;

        public int Year
        {
            get { return Y; } 
            set { Y = value; }

        }
        public double Sale
        {
            get { return S; }
            set { S = value; }
        }

        public SSales (int _year, double _sales)
        {

            Y = _year;
            S = _sales;

        }

private void Sortbutton_Click(object sender, EventArgs e)
    {
        listBox1.Items.Clear();
        if (yearradio.Checked)
        {
            int temp = 0;
            for (int i = 0; i < bubble.Length - 1; i++)
            {
                for (int j = 0; j < bubble.Length - 1; j++)
                {
                    if (bubble[i + 1].Year < bubble[i].Year)
                    {
                        temp = bubble[i].Year;
                        bubble[i].Year = bubble[i + 1].Year;
                        bubble[i + 1].Year = temp;
                    }
                }
            }

        }
        if (salesradio.Checked)
        {
            double temp2 = 0;
            for (int i = 0; i < bubble.Length - 1; i++)
            {
                for (int j = 0; j < bubble.Length - 1; j++)
                {
                    if (bubble[i + 1].Sale > bubble[i].Sale)
                    {
                        temp2 = bubble[i].Sale;
                        bubble[i].Sale = bubble[i + 1].Sale;
                        bubble[i + 1].Sale = temp2;

                    }
                }
            }
        }
        for (int i = 0; i < bubble.Length; i++)
        {

            listBox1.Items.Add(bubble[i].ToString());

        }

    }

虽然我的冒泡排序算法运行得非常好,但它们只会随着每次单击排序按钮而递增排序。我需要通过单击 1 次对列表框进行完全排序。

另外,就像我现在的代码一样,Years 和 Sales 完全相互独立地重组。当 Sales 索引发生变化时,相应的 Year 索引将保持在同一位置,反之亦然。

我猜想使用 int j 的 for 循环会起作用,但我不确定如何实现它。如有任何帮助,我们将不胜感激!

我看到两个问题。其中之一是 setting/exchanging 结构的属性,而不是结构本身。这就是为什么您的销售额和年份不同步的原因。您需要交换整个结构。类似于:

                    var temp = bubble[i];
                    bubble[i] = bubble[i + 1];
                    bubble[i + 1] = temp;

这就引出了第二个问题。您有一个使用索引变量 i 和 j 的双循环。您的交换只使用 i。如果您正在尝试进行冒泡排序,您真的需要嵌套循环吗?考虑可以在此处 bubble sort 找到的伪代码实现,您应该很快就能看到问题所在。仿照该示例为您的排序建模。

我猜你做冒泡排序是出于学习/练习的原因。如果不是,您应该只使用内置的 Array.Sort()Enumerable.OrderBy() 或类似的东西。

你有很多地方做错了。我有改进后的代码,我将在下面解释

struct SSales {
    public int Year { get; set; } // use auto-properties for brevity

    public double Sale { get; set; }  // use auto-properties for brevity

    public SSales(int year, double sales) {
        Year = year;
        Sale = sales;
    }
}

// Use a generic routine to Swap, instead of replicating the code multiple times
// Note that we are passing by reference so the actual array eventually gets sorted
// Also, don't swap the properties, but the whole record. Else it will corrupt your data
static void Swap<T>(ref T obj1, ref T obj2) {
    var temp = obj1;
    obj1 = obj2;
    obj2 = temp;
}

// Write the sort routine separately. Sorts usually just need a way to compare records, which can be provided by Caller (IoC pattern)
static void Sort<T>(T[] items, Func<T, T, int> comparer) {
    for (int i = 0; i < items.Length - 1; i++) {
        // Every execution of the inner loop will bubble-up the largest element in the range
        // Your array is getting sorted from the end, so you don't need to re-compare the already sorted part
        for (int j = 0; j < items.Length - 1 - i; j++) {
            if (comparer(items[j], items[j + 1]) > 0) // call the generic user provided comparer to know the sequence
                Swap(ref items[j], ref items[j + 1]); // use teh generic swapper to swap elements in the array
        }
    }
}


private void Sortbutton_Click(object sender, EventArgs e) {
    listBox1.Items.Clear();

    if (yearradio.Checked) {
        // Invoke the Sort routine, with the required comparer
        Sort(bubble, (a, b) => a.Year - b.Year);
    }

    if (salesradio.Checked) {
        // Invoke the Sort routine, with the required comparer
        Sort(bubble, (a, b) => (int)(a.Sale - b.Sale));
    }

    for (int i = 0; i < bubble.Length; i++) {
        listBox1.Items.Add(bubble[i].ToString());
    }

}

希望这能阐明您面临的问题,并帮助您学习如何编写更好的 C# 代码。