使用struct成员时冒泡排序

时间:2017-03-15 17:07:50

标签: c# sorting struct bubble-sort

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

        }

    }

虽然我的气泡排序算法工作得很好,但它们只能在每次单击“排序”按钮时逐步排序。我需要通过单击一下完全排序列表框。

enter image description here

此外,正如我的代码现在,年和销售完全独立地重新组织。当Sales索引更改时,相应的Year索引将保留在同一位置,反之亦然。

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

2 个答案:

答案 0 :(得分:1)

我看到两个问题。您正在设置/交换结构的属性,而不是结构本身。这就是为什么您的销售和年份不同步的原因。您需要交换整个结构。类似的东西:

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

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

答案 1 :(得分:0)

我猜你会因学习/练习原因而冒泡。如果不是,您应该使用内置的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#代码。