使用结构成员时的冒泡排序
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# 代码。
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# 代码。