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());
}
}
虽然我的气泡排序算法工作得很好,但它们只能在每次单击“排序”按钮时逐步排序。我需要通过单击一下完全排序列表框。
此外,正如我的代码现在,年和销售完全独立地重新组织。当Sales索引更改时,相应的Year索引将保留在同一位置,反之亦然。
我猜测使用int j的for循环会起作用,但我不确定如何实现它。任何帮助将不胜感激!
答案 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#代码。