bubble sort and foreach index - c#

I have some code below for a button click event,
which uses bubble sort. I am a little bit unclear
of the use. Trying to sort an array in ascending
order. Also I have to use a foreach and need to
get an index from it some how.
An attempt int z = a.GetEnumerator(); does not work. int k = 0;//Cheat to get code working
int k = 0;//Cheat to get code working
foreach (BankAccount BankAccount in a)
//for (int i = 0; i < a.Length; i++)
{
//int z = a.GetEnumerator();
lstBefore.Items.Add(a[k].show());
k += 1;//Cheat to get code working
}
//if (a[0] is IComparable)
//{
//Sort.BubbleSort(a);//Sort a
k = 0;//Cheat to get code working
for (int i = 0; i < a.Length; i++)
{
lstAfter.Items.Add(a[k].show());
//else MessageBox.Show("unable to sort");
k += 1;//Cheat to get code working
}
//}
//else MessageBox.Show("unable to sort");
class Sort : IComparable
{
public static void BubbleSort(IComparable[] arr)
{
bool swap = true;
IComparable temp;
for (int i = 0; swap; i++)
{
swap = false;
for (int j = 0; j < (arr.Length - (i + 1)); j++)
{
//int test = arr[j].CompareTo(arr[j + 1]);
if (arr[j].CompareTo(arr[j + 1]) > 0)
//If this balance is < than next balance
{
temp = (IComparable)arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swap = true;
}
}
}
}
}
Also I have
public class BankAccount : IComparable, IComparable<BankAccount>//Class BackAccount - //Icomarable
{
private decimal balance;
private string FullName;
//...
public int CompareTo(BankAccount that)//Compare To
{
if (this.balance > that.balance) return -1;//If this balance is > than next balance
if (this.balance == that.balance) return 0;//If this balance is = to next balance
return 1;//If this balance is < than next balance
//return this.balance.CompareTo(that.balance);
}
}
Thanks,

Looks like you just need to implement CompareTo in your Sort class (not just the BankAccount class).

First, a foreach does not have an index in any way. If you need a index, use a for loop.
Second, The Sort class have not to implement IComparable (which causes the error). It's a Comparer, not compared. It can implement IComparer if you want to, or to be static.
And why do you diving into bubble sort implementation, when you have Array.Sort or List.Sort methods, that implements QuickSort and is sure faster and better? I would avoided this.

Related

Why is Big O of Bubble sort Quadradic time if last interaction is dismissed?

I have the following Bubble sort Algorithm:
public void BubbleSort(int[] arr, int start, int end)
{
int instructions = 0;
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i = 0; i < arr.Length - 1; i++)
{
//instructions++;
for (int j = i + 1; j < arr.Length; j++)
{
instructions++;
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
swapped = true;
}
}
}
}
Console.WriteLine("instructions++ " + instructions);
}
if you print instructions you will see it is exactly: (n^2) - n
So why do we disregard -n?
Is it considered constant even though it is variable to the input size(it would be weird buy hey..)?
Time compelxity works as such. For large n values in this case, linear n does not matter. For eg if we are talking about 10 million numbers the value (10^6)^2 is far greater than 10^6. So even though it exists the other factor dwarfs it for large n so it makes it easier to disregard it.

Sorting a list of objects of multiple data types

I have this class in my code
class Stock
{
public DateTime Date;
public string Day;
public double Open, Close, Diff;
public int Volume;
public Stock(double open, double close, double diff, int volume, string day, DateTime date)
{
this.Open = open;
this.Close = close;
this.Diff = diff;
this.Volume = volume;
this.Day = day;
this.Date = date;
}
}
In another class i want to create a bubble sort that will sort a List of Stocks (List<Stocks>) passed to it, i am having multiple issues with this the main problem is the data types, its not easy comparing two values when they could be a string, int, double or DateTime. I have done it with a method that uses TryParse to check for valid data type, but im looking for a nice clean solution, this is my attempt so far
public void BubblesortBy(int sortBy, List<Stock> Stocks)
{
Type objType = typeof(Stock);
FieldInfo[] fields = objType.GetFields();
Stock temp = null;
int loopCount = 0;
bool doBreak = true;
for (int i = 0; i < Stocks.Count; i++)
{
doBreak = true;
for (int j = 0; j < Stocks.Count - 1; j++)
{
if (Compare(fields[sortBy - 1].FieldType.ToString(), fields[sortBy].GetValue(Stocks[j]), fields[sortBy].GetValue(Stocks[j+1])))
{
temp = Stocks[sortBy + 1];
Stocks[sortBy + 1] = Stocks[sortBy];
Stocks[sortBy] = temp;
doBreak = false;
}
loopCount++;
}
if (doBreak) { break; /*early escape*/ }
}
}
The int passed to it determines whether to sort by, which is why i am using reflection so the variables are accessible by numbers.
Date
Day
Open
Close
Difference
Volume
You shouldn't assume that the fields returned by GetFields will be in a certain order.
The GetFields method does not return fields in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which fields are returned, because that order varies.
One option is to use lambdas like LINQ's OrderBy method does. Using generic types can also make your code more reusable, and make things like your Compare method simpler.
public void BubblesortBy<TSource, TKey>(Func<TSource, TKey> keySelector,
List<TSource> stocks)
{
int loopCount = 0;
bool doBreak = true;
for (int i = 0; i < stocks.Count; i++)
{
doBreak = true;
for (int j = 0; j < stocks.Count - 1; j++)
{
if (Compare(keySelector(stocks[j]), keySelector(stocks[j+1])))
{
TSource temp = stocks[j + 1];
stocks[j + 1] = stocks[j];
stocks[j] = temp;
doBreak = false;
}
loopCount++;
}
if (doBreak) { break; /*early escape*/ }
}
}
private bool Compare<T>(T l, T r)
{
return Comparer<T>.Default.Compare(l, r) > 0;
}
// use like
BubblesortBy(x => x.Close, myList);
Why are you implementing sorting yourself? Look into IComparable
Edit:
A nice and type safe way to pass the field to sort by into the method without refection, would be:
BubblesortBy(x => x.FieldName, stockes);
public void BubblesortBy<T>(Func<Product, T> sortBy, List<Stock> Stocks)
{
Stock temp = null;
int loopCount = 0;
bool doBreak = true;
for (int i = 0; i < Stocks.Count; i++)
{
doBreak = true;
for (int j = 0; j < Stocks.Count - 1; j++)
{
if (Compare(sortBy(Stocks[j]), sortBy(Stocks[j + 1])))
{
temp = Stocks[sortBy + 1];
Stocks[sortBy + 1] = Stocks[sortBy];
Stocks[sortBy] = temp;
doBreak = false;
}
loopCount++;
}
if (doBreak)
break; /*early escape*/
}
}

indexOutofRange BubbleSort when using inputbox

Its been bugging me for hours because it is always returning 0 at numbers[i] and I cant figure out the problem. code worked for a different program but I had to change it so it could have a custom array size and that's when everything went wrong.
any help would be great.
Thanks in advance.
int[] numbers = new int[Convert.ToInt16(TxtArray.Text)];
int j = 0;
for (j = numbers.Length; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 1; i++)
{
string NumbersInput = Microsoft.VisualBasic.Interaction.InputBox("Enter Numbers to be sorted",
"Numbers Input", "", -1, -1);
numbers[i] = Convert.ToInt16(NumbersInput);
//returns 0 in if statement
if (numbers[i] < numbers[i + 1])
{
int intTemp = 0;
intTemp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = intTemp;
}
}
}
for (int i = 0; i < numbers.Length; i++)
{
LstNumbers.Items.Add(numbers[i]);
}
private void button1_Click(object sender, EventArgs e)
{
int sizeOfArrayInt = Convert.ToInt32(arraySize.Text);
int[] array = new int[sizeOfArrayInt];
string numbers = arrayValues.Text;
string[] numbersSplit = numbers.Split(',');
int count = 0;
foreach (string character in numbersSplit)
{
int value;
bool parse = Int32.TryParse(character, out value);
if (value != null)
{
array[count] = value;
}
count++;
}
array = this.SortArray(array);
foreach (int item in array)
{
this.listBox.Items.Add(item);
}
}
private int[] SortArray(int[] arrayToSort)
{
//int[] sortedArray = new int[arrayToSort.Length];
int count = arrayToSort.Length;
for (int j = count; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 2; i++)
{
if (arrayToSort[i] < arrayToSort[i + 1])
{
int intTemp = 0;
intTemp = arrayToSort[i];
arrayToSort[i] = arrayToSort[i + 1];
arrayToSort[i + 1] = intTemp;
}
}
}
return arrayToSort;
}
strong text
This I got to work as a Windows Form and the output displays in the list box as each array item or individual i iteration over the array. Of course there is no error checking. Hope that helps.
Setting aside the strangeness of how you are working with text boxes, your problem with throwing an exception would happen even without them because it lies here, in your inner loop:
for (i = 0; i <= j - 1; i++)
Suppose that numbers.Length == 2. This means that j == 2. So on the first time through the outer loop, you hit the inner loop with these conditions. The first time through, i == 0. You get to the if statement:
if (numbers[i] < numbers[i + 1])
numbers[0] exists, and numbers[1] exists, so this iteration goes through fine and i is incremented.
Now i == 1. Now the loop checks its boundary condition. i <= j - 1 == true, so the loop continues. Now when you hit that if statement, it tries to access numbers[i + 1], i.e., numbers[2], which does not exist, throwing an IndexOutOfRangeException.
Edit: Came back and realized that I left out the solution (to the exception, anyway). For the bubble sort to work, your inner loop's boundary condition should be i <= j - 2, because j's initial value is == numbers.Length, which is not zero-based, while array indexes are.
Second Edit: Note that just using a List won't actually solve this problem. You have to use the right boundary condition. Trying to access list[list.Count()] will throw an ArgumentOutOfRangeException. Just because a List will dynamically resize doesn't mean that it will somehow let you access items that don't exist. You should always take time to check your boundary conditions, no matter what data structure you use.

Insertion Sorting c#

Can you guys please help me with basic insertion sorting in C#. I have a list of names and city of residence in a array and need to sort this array by comparing the city of residence. List has to be sorted in alphabetical order. Comparator has been set up and works I'm just kinda lost with the insertion sorter programming as this is the first time we are doing that method of sorting.
Here's what I've tried so far:
public void InsertionSort()
{
for (int i = 0; i < Count; i++)
{
Student cur = Attendees[i];
for (int j = 0; j < Count; j++)
{
Student Sel = Attendees[j];
if (cur.CompareTo(Sel) < 0)
{
Student temp = Attendees[j];
Attendees[j] = Attendees[i];
for (int k = i; k > j; k--)
Attendees[k] = Attendees[k - 1];
Attendees[k + 1] = temp;
}
}
}
}
Try like this...
public void InsertionSort()
{
for (int i = 0; i < Count; i++)
{
int j = i;
While(j > 0)
{
Student cur = Attendees[j];
Student sel = Attendees[j-1];
if (cur.CompareTo(Sel) < 0)
{
Student temp = cur;
cur = sel;
sel = temp;
j--
}
else
break;
}
}
}
public void InsertionSort()
{
for (int i = 1; i < Count; i++) // Iterate beginning at 1, because we assume that 0 is already sorted
{
for (int j = i; j > 0; j--) // Iterate backwards, starting from 'i'
{
Student cur = Attendees[j - 1];
Student tbs = Attendees[j]; // 'tbs' == "to be sorted"
if (cur.CompareTo(tbs) < 0) // usually, classes that implement 'CompareTo()' also implement 'operator <()', 'operator >()' and 'operator ==()', so you could have just written 'cur < tbs'
{
Student temp = Attendees[j];
Attendees[j] = Attendees[j - 1];
Attendees[j - 1] = temp;
}
else
break; // since 'tbs' is no longer > 'cur', it is part of our sorted list. We don't need to sort that particular 'tbs' any further
}
}
}
Keep in mind, that this algorithm sorts your list in descending order.
int[] newarr = {2,1,5,3,7,6};
int a, b;
for (int i = 1; i < newarr.Length; i++)
{
a = newarr[i];
b = i - 1;
while(b>=0 && newarr[b]>a)
{
newarr[b+1] = newarr[b];
b=b-1;
}
newarr[b+1] = a;
}

Bubble Sorting not Giving Correct Result Code Attached C#?

My sorting code not giving correct result it is not sortint the given list properly while i am not getting the error please check it,
static void Main(string[] args)
{
List<int> a = new List<int>(new int[] { 3, 7, 6, 1, 8, 5 });
int temp;
// foreach(int i in a)
for(int i=1; i<=a.Count; i++)
for(int j=0; j<a.Count-i; j++)
if (a[j] > a[j + 1])
{
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
Console.WriteLine(a[j]);
}
Console.Read();
}
i could not understand your code and i do not know C#. But anyways, here is the sorting logic for bubble sort (written in c).
//assuming there are n elements in the array a[]
for(i=0; i<n; i++)
{ for(j=1; j<n-i; j++)
{ if(a[j] < a[j-1])
{ temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
and you can also refer to:
www.sorting-algorithms.com/bubble-sort
What you posted is not a implementation of the Bubble Sort algorithm. You forgot to loop while no number is swapped anymore. Here is a Bubble Sort implementation written by John Skeet. The stillGoing check is what at least is missing in your implementation:
public void BubbleSort<T>(IList<T> list);
{
BubbleSort<T>(list, Comparer<T>.Default);
}
public void BubbleSort<T>(IList<T> list, IComparer<T> comparer)
{
bool stillGoing = true;
while (stillGoing)
{
stillGoing = false;
for (int i = 0; i < list.Length-1; i++)
{
T x = list[i];
T y = list[i + 1];
if (comparer.Compare(x, y) > 0)
{
list[i] = y;
list[i + 1] = x;
stillGoing = true;
}
}
}
}
remove the console.write from the nested loops. place console.write outside the nested loops in a new for loop or foreach.
then you will get the correct order. otherwise, the logic of bubble sort is correct

Categories

Resources