C# insertion sort after each value - c#

How can I run the Insertion Sort code after each time user enters a value. Please notice that I don't have much knowledge about programming so showing an example or ready to use code would be appreciated.
Console.Write("How long the Insertion sort list should be?: ");
var countString = Console.ReadLine();
int count = Convert.ToInt32(countString);
int[] data = new int[count];
for (int i = 0; i < count; i++)
{
var input = Console.ReadLine();
data[i] = Convert.ToInt32(input);
Console.WriteLine(input); // << HERE THE SORTING SHOULD HAPPEN AFTER EACH VALUE THAT I ADD.
}
int j = 0;
int help = 0;
for (int i = 1; i < data.Length; i++)
{
j = i;
help = data[i];
while (j > 0 && help < data[j - 1])
{
data[j] = data[j - 1];
j--;
}
data[j] = help;
}
foreach (var i in data)
{
Console.Write("{0}, ", i);
}
}

You can visually divide your code into two parts. The first part is for inserting the values. The second part sorts these values. So you have to cut the second part and insert at the place, where sorting should happen, I hope you will find this place ;)
Also think that you should replace i in the second for with something else, for example with k
Good luck

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.

How can I fill a 2d array recursively?

I have a string filled with 9 numbers. I want to fill a 3x3 array with the numbers. I've managed to do it using a foreach and 2 for loops, but I feel this is quite messy. How can I modify my code to recursively enter the values into the array? This is my code currently:
int[,] matrix = new int[3, 3];
if(key.Length < 9 || key.Length > 9)
{
keyfield.GetComponent<InputField>().text = " Key Not Valid";
}
else
{
foreach(char c in key)
{
for (int k = 0; k < 3; k++)
{
for (int j = 0; j < 3; j++)
{
matrix[j, k] = c - 0;
}
}
}
}
Note, I'm working with Unity.
Well, just iterate over the chars in your key and assign them to the array, one field at a time. It's just a matter of calculating the correct columns and rows:
for (int i = 0; i < 9; ++i)
{
int row = i / 3;
int col = i % 3;
matrix[row, col] = (int)key[i];
}
Also note that neither the code in your question nor the code in my answer solves the problem in a recursive way. Recursion is given when a method calls itself directly or indirectly, which is not required to solve this particular problem.

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.

Can you provide alternative algorithms for sorting arrays?

Ive written the following method which sorts an array by copying the biggest values into another array. I would like to see alternatives to this approach. for example an approach which swaps the values in the primary array itself, thereby eliminating the need for a secondary array to copy the values to.
I do not want to use pre written .net library methods such as Array.sort or etc as my main goal is only to practice in writing algorithms.
also if anyone can tell me the weak points of the below code and its shortcomings and how it can be improved, it would be greatly appreciated.
thank you
private static void sortArray(int[] array)
{
int[] sorted = new int[array.Length];
int curMax = 0;
int bigIndex = 0;
for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length; j++)
{
if (array[j] > curMax)
{
bigIndex = j;
curMax = array[j];
}
}
sorted[i] = array[bigIndex];
array[bigIndex] = 0;
curMax = 0;
}
}
example of bubble sort:
private static void sortArray(int[] array)
{
bool lastExchange;
do
{
lastExchange = false;
for (int i = 1; i < array.Length; i++)
{
if (array[i - 1] > array[i])
{
lastExchange = true;
int temp = array[i - 1];
array[i - 1] = array[i];
array[i] = temp;
}
}
} while (lastExchange);
}
You arlgorithm is (excuse me for saying it), pretty much as inefficient as a sorting algorithm can be. You could for example make it more efficient by simply swapping items in the array instead of leaving unused values in the array. By doing that you will reduce the number of items that you have to look through for each iteration:
private static void sortArray(int[] array) {
for (int i = 0; i < array.Length; i++) {
int largest = array[i];
int largeIndex = i;
for (int j = i + 1; j < array.Length; j++) {
if (array[j] > largest) {
largeIndex = j;
largest = array[j];
}
}
array[largeIndex] = array[i];
array[i] = largest;
}
}
(Another problem with your algorithm is that it doesn't work with negative values, or zero values.)
One of the simplest sorting algorithms is bubble sort:
private static void sortArray(int[] array) {
bool cont = true;
while (cont) {
cont = false;
for (int i = 1; i < array.Length; i++) {
if (array[i - 1] > array[i]) {
cont = true;
int temp = array[i - 1];
array[i - 1] = array[i];
array[i] = temp;
}
}
}
}
Take a look at http://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms for examples of sorting algorithms. You can click through to any one you want and try implementing them yourself based on their description.
What you have at the moment is a selection sort, which is fairly easy to implement but isn't all that great as far as sorting algorithms go. A good sorting algorithm will have an n(log n) complexity (typically a log n search * n items).
Have you already thought about implementing the following sort algorithms:
Bubble Sort
Quick Sort
Greetings,
Update 1:
A very good page about sorting algorithms (visualized) is http://www.sorting-algorithms.com/
i like Bucket Sort and it's extended Radix-Sort Best !
two reasons:
cant overlook the O(n) over O(nLog(n))
i love hash tables and it is kinda the same concept
Also take a look at Heap Sort, which is a nice algorithem.

C# populate array with unique ints No Linq or ArrayLists;

This code is buggy but can't figure out why ... want to populate an array with 7 unique random integers without using arraylists or linq! I know the logic is not okay...
class Program
{
static void Main(string[] args)
{ int current;
int[] numbers = new int[7]; // size of that array
Random rNumber = new Random();
current = rNumber.Next(1, 50);
numbers[0] = current;
Console.WriteLine("current number is {0}", current);
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < numbers.Length; j++)
{
do
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
}
else
{
numbers[j++] = current;
break;
}
}while (current == numbers[j]);
}//inner for
}//outer for
for (int l = 0; l < 7; l++) // DISPLAY NUMBERS
{
Console.WriteLine(numbers[l]);
}
}// main
}//class
want to populate an array with 7 unique integers without using
arraylists or linq!
int[] list = new int[7];
for (int i = 0; i < list.Length; i++)
{
list[i] = i;
}
EDIT
I changed your inner loop, if the random number is already in the array; create a new random and reset j to 0.
for (int i = 1; i < 7; i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < numbers.Length; j++)
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
j = 0; // reset the index iterator
}
}//inner for
numbers[i] = current; // Store the unique random integer
}//outer for
I presume you are looking for random numbers, so the other answer is not what you are looking for.
There are a couple of issues here.
The inner loop is testing for duplicates. However, it is looking from 0 through the end of the array since it is using numbers.length. This should probably be i, to compare with already set values. numbers.length is always 7 regardless of whether or not you set any of the elements.
the assignment is using j, so presuming the first element is not a duplicate, it will be overwritten each time. That should be numbers[i] = current;. No ++ necessary as the for is handling the incrementing.
if you determine that a number is a duplicate, j should be reset to zer to check against the entire list again rather than having the while in the middle.
Without a complete rewrite, the changes will look something like this:
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < i; j++) //----------------- loop through set values
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
j = 0; // -----------------------reset the counter to start over
}
}//inner for
// if we got here there is no duplicate --------------------------------
numbers[i] = current;
}//outer for
(Please note that I have not tested this code, just added the changes)
you keep overwriting the same indexes in the else, and also checking too many indices causing the first to show up as a duplicate at all times which was false...
change it to:
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < i; j++) ///< change to j < i. no need to check the others
{
do
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
}
else
{
numbers[i] = current; ///< not j++ but i to prevent writing at the same locations over and over again
break;
}
}while (current == numbers[j]);
}//inner for
}//outer for
What about this?
int[] list = new int[7];
var rn = new Random(Environment.TickCount);
for (int i = 0; i < 7; i++)
{
var next = rn.Next(1, 50);
while(Contains(list, next))
{
next = rn.Next(1, 50);
}
list[i] = next;
}
private bool Contains(IEnumerable<int> ints, int num)
{
foreach(var i in ints)
{
if(i = num) return true;
}
return false;
}

Categories

Resources