Related
The following picture is retrieved from Wikipedia:
I haven't understood this part:
I have two questions here:
Where did they obtain [8,4,1,2] from and what did they want to tell us by that?
Take a look at cell [0, 0] whose value is 13. If I go clockwise along with its contouring values, I obtain the binary string 0010 which is 2. How does the 1st cell-value become 13?
.
enum What
{
lines, surface, both
}
class Program
{
public static void Print(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
Console.Write(data[i,j] + ", ");
}
Console.WriteLine();
}
}
public static int[,] normalize(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
if (data[i, j] > 1)
{
data[i, j] = 0;
}
else
{
data[i, j] = 1;
}
}
}
return data;
}
public static int[,] marching_square(int x, int y, int[,] data, int isovalue, What what)
{
int xn = x;
int yn = y;
data = normalize(data, xn, yn);
int[,] bitMask = new int[xn - 1, yn - 1];
for (int j = 0; j < yn - 1; j++)
{
for (int i = 0; i < xn - 1; i++)
{
StringBuilder sb = new StringBuilder();
sb.Append(data[i, j]);
sb.Append(data[i, j + 1]);
sb.Append(data[i + 1, j]);
sb.Append(data[i + 1, j + 1]);
bitMask[i, j] = Convert.ToInt32(sb.ToString(), 2);
}
}
return bitMask;
}
static void Main(string[] args)
{
int[,] data = new int[,] {
{ 1,1,1,1,1 },
{ 1,2,3,2,1 },
{ 1,3,3,3,1 },
{ 1,2,3,2,1 },
{ 1,1,1,1,1 }
};
Print(data, 5,5);
int[,] bitMask = marching_square(5,5,data, 0, What.lines);
Print(bitMask, 4, 4);
}
}
Output:
1, 1, 1, 1, 1,
1, 2, 3, 2, 1,
1, 3, 3, 3, 1,
1, 2, 3, 2, 1,
1, 1, 1, 1, 1,
14, 10, 10, 11,
12, 0, 0, 3,
12, 0, 0, 3,
13, 5, 5, 7,
I inverted the bits. But, the output looks different.
quick sort is slower than normal interative sort?
i have checked with console application in Visual studio. Am i making any mistake here or please tell me the reason.. The output shows that iterative sort is much more efficient than QUick sort
class Program
{
static Random rr = new Random();
private static void Quick_Sort(int[] arr, int left, int right)
{
if (left < right)
{
int pivot = Partition(arr, left, right);
if (pivot > 1)
{
Quick_Sort(arr, left, pivot - 1);
}
if (pivot + 1 < right)
{
Quick_Sort(arr, pivot + 1, right);
}
}
}
private static int Partition(int[] arr, int left, int right)
{
int pivot = arr[9];
while (true)
{
while (arr[left] < pivot)
{
left++;
}
while (arr[right] > pivot)
{
right--;
}
if (left < right)
{
if (arr[left] == arr[right]) return right;
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
else
{
return right;
}
}
}
static void Main(string[] args)
{
int[] arr = new int[] { 2, 5, -4, 11, 0, 18, 22, 67, 51, 6, 27 };
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
Quick_Sort(arr, 0, arr.Length - 1);
sw.Stop();
Console.WriteLine(sw.ElapsedTicks.ToString());
sw.Reset();
arr = new int[] { 2, 5, -4, 11, 0, 18, 22, 67, 51, 6, 27 };
sw.Start();
for (int i = 0; i < arr.Length; i++)
{
for (int j = i; j < arr.Length; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks.ToString());
//Console.WriteLine();
//Console.WriteLine("Sorted array : ");
foreach (var item in arr)
{
Console.Write(" " + item);
}
Console.WriteLine();
Console.ReadKey();
}
}
the output of it
Quick sort- 3071 ticks
Normal sort - 7 ticks
Im trying to sort a integer Array. My Quick Sort algorithm works fine with 10 or less numbers, but as soon as I add more, it doesnt sort them correctly?
It works the same way, with or without Shuffle(left, right), so I dont think the problem is there.
Im going to use the code for sorting a large amount of numbers and I think Quick Sort is the most efficient choice for my data.
private static int[] intArray;
static void Main(string[] args)
{
data = new int[] { 1, 9, 10, 2, 4, 5, 6, 3, 257, -6 };
int N = data.Length;
intArray = new int[N];
long before = Environment.TickCount;
long after = Environment.TickCount;
QuickSort(0, N - 1);
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(data[i]);
}
}
private static int Pivot(int left, int right)
{
int pivot = data[left];
while (true)
{
while (data[left] < pivot)
{
left++;
}
while (data[right] > pivot)
{
right--;
}
if (left < right)
{
if (data[left] == data[right])
{
return right;
}
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
else
{
return right;
}
}
}
private static void QuickSort(int left, int right)
{
Shuffle(left, right);
if (left < right)
{
int pivot = Pivot(left, right);
if (pivot > 1)
{
QuickSort(left, pivot - 1);
}
else if (pivot + 1 < right)
{
QuickSort(pivot + 1, right);
}
}
}
Fixes noted in comments. The shuffle makes it relatively slow:
private static int[] data; // fix
private static int Pivot(int left, int right)
{
int pivot = data[left];
while (left <= right)
{
while (data[left] < pivot)
{
left++;
}
while (data[right] > pivot)
{
right--;
}
if (left <= right) // fix
{
// fix deleted 4 lines
int temp = data[left];
data[left] = data[right];
data[right] = temp;
left++; // fix
right--; // fix
}
}
return right; // fix
}
private static void QuickSort(int left, int right)
{
Shuffle(left, right);
if (left < right)
{
int pivot = Pivot(left, right);
QuickSort(left, pivot); // fix
QuickSort(pivot+1, right); // fix
}
}
public static void Shuffle(int lo, int hi)
{
Random rand = new Random();
for (int i = lo; i <= hi; i++)
{
int r = i + rand.Next(hi + 1 - i);
int t = data[i]; data[i] = data[r]; data[r] = t;
}
}
static void Main(string[] args)
{
data = new int[] { 1, 9, 10, 2, 4, 5, 6, 3, 257, -6 }; // fix
long before = Environment.TickCount;
QuickSort(0, data.Length - 1);
long after = Environment.TickCount;
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(data[i]);
}
Console.WriteLine(after - before);
}
Alternative code based on standard Hoare partition scheme, with data passed as a parameter.
static public void Quicksort(int [] data, int lo, int hi)
{
if (lo >= hi)
return;
int p = data[(lo + hi) / 2];
int i = lo, j = hi;
i--; // partition
j++;
while (true)
{
while (data[++i] < p) ;
while (data[--j] > p) ;
if (i >= j)
break;
int t = data[i];
data[i] = data[j];
data[j] = t;
}
Quicksort(data, lo, j); // recurse
Quicksort(data, j + 1, hi);
}
static void Main(string[] args)
{
const int SIZE = 10*1024*1024;
int [] data = new int[SIZE];
Random r = new Random(1);
Stopwatch sw = new Stopwatch();
for (int i = 0; i < data.Length; i++)
data[i] = r.Next(data.Length);
sw.Start();
Quicksort(data, 0, data.Length - 1);
sw.Stop();
for (int i = 1; i < data.Length; i++)
{
if(data[i] < data[i-1])
Console.WriteLine("failed");
}
Console.WriteLine("milliseconds: {0:D}\n",sw.ElapsedMilliseconds);
}
I am doing a bubble sort exercise and my feeling is that it is very close to correct.
As it is at the moment I am presented with an eternal loop.
Where does the fault lie ?
static void Main(string[] args)
{
int[] numbers = { 2, 4, 8, 5, 88, 55, 32, 55, 47, 8, 99, 120, 4, 32 };
int temporary;
bool sorted;
do
{
sorted = false;
for (int i = 0; i < numbers.Length - 1; i++)
{
int a = numbers[i];
int b = numbers[i + 1];
if (a > b)
{
temporary = a;
a = b;
b = temporary;
sorted = true;
}
}
Console.WriteLine("sorted");
} while (sorted == true);
foreach (int i in numbers)
{
Console.Write(i + " ");
}
}
A better approach in C# is to use a generic bubble sort
public void BubbleSort<T>(IList<T> list);
{
BubbleSort<T>(list, Comparer<T>.Default);
}
public void BubbleSortImproved<T>(IList<T> list, IComparer<T> comparer)
{
bool stillGoing = true;
int k = 0;
while (stillGoing)
{
stillGoing = false;
for (int i = 0; i < list.Count - 1 - k; 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;
}
}
k++;
}
}
A brief explanation of this algorithm is given by Jon Skeet in his answer here. "It uses an arbitrary comparer, but lets you omit it in which case the default comparer is used for the relevant type. It will sort any (non-readonly) implementation of IList, which includes arrays."
I hope this helps.
You exchange a with b but you DON'T do anything to your input array. Thus, you are constantly exchanging values in memory but the original array is not changed. Try:
for ( int i = 0; i < numbers.Length - 1; i++ )
{
if ( numbers[i] > numbers[i + 1] )
{
temporary = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temporary;
sorted = true;
}
}
You are not writing the results back onto the array.
Use this instead:
//temporary = a;
//a = b;
//b = temporary;
numbers[i] = b;
numbers[i + 1] = a;
It should be
if (numbers[i] > numbers[i + 1])
{
temporary = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temporary;
sorted = true;
}
changes made in a,b doesn't reflect in numbers[i] numbers[i+1] because a and b are mere copy of numbers[i] numbers[i+1]..
Here is an working example:
static void Main(string[] args)
{
int[] numbers = { 2, 4, 8, 5, 88, 55, 32, 55, 47, 8, 99, 120, 4, 32 };
int temporary;
bool sorted;
do
{
sorted = false;
for (int i = 0; i < numbers.Length - 1; i++)
{
if (numbers[i] > numbers[i + 1])
{
temporary = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temporary;
sorted = true;
}
}
Console.WriteLine("sorted");
} while (sorted == true);
foreach (int i in numbers)
{
Console.Write(i + " ");
}
}
I found quicksort algorithm from this book
This is the algorithm
QUICKSORT (A, p, r)
if p < r
q = PARTITION(A, p, r)
QUICKSORT(A, p, q-1)
QUICKSORT(A, q+1, r)
PARTITION(A, p, r)
x=A[r]
i=p-1
for j = p to r - 1
if A <= x
i = i + 1
exchange A[i] with A[j]
exchange A[i+1] with A[r]
return i + 1
And I made this c# code:
private void quicksort(int[] input, int low, int high)
{
int pivot_loc = 0;
if (low < high)
pivot_loc = partition(input, low, high);
quicksort(input, low, pivot_loc - 1);
quicksort(input, pivot_loc + 1, high);
}
private int partition(int[] input, int low, int high)
{
int pivot = input[high];
int i = low - 1;
for (int j = low; j < high-1; j++)
{
if (input[j] <= pivot)
{
i++;
swap(input, i, j);
}
}
swap(input, i + 1, high);
return i + 1;
}
private void swap(int[] ar, int a, int b)
{
temp = ar[a];
ar[a] = ar[b];
ar[b] = temp;
}
private void print(int[] output, TextBox tbOutput)
{
tbOutput.Clear();
for (int a = 0; a < output.Length; a++)
{
tbOutput.Text += output[a] + " ";
}
}
When I call function like this quicksort(arr,0,arr.Length-1); I get this error An unhandled exception of type 'System.StackOverflowException' occurred it pass empty array... when call function like this quicksort(arr,0,arr.Length); I get error Index was outside the bounds of the array. on this line int pivot = input[high]; but array passed successfully.
I also want to print it like this print(input,tbQuick); but where to place it so it would print when quicksort finished?
You did not properly implement the base case termination, which causes quicksort to never stop recursing into itself with sublists of length 0.
Change this:
if (low < high)
pivot_loc = partition(input, low, high);
quicksort(input, low, pivot_loc - 1);
quicksort(input, pivot_loc + 1, high);
to this:
if (low < high) {
pivot_loc = partition(input, low, high);
quicksort(input, low, pivot_loc - 1);
quicksort(input, pivot_loc + 1, high);
}
In addition to Deestan's answer, you also have this wrong:
for (int j = low; j < high-1; j++)
It should be:
for (int j = low; j < high; j++)
Just in case you want some shorter code for Quicksort:
IEnumerable<int> QuickSort(IEnumerable<int> i)
{
if (!i.Any())
return i;
var p = (i.First() + i.Last) / 2 //whichever pivot method you choose
return QuickSort(i.Where(x => x < p)).Concat(i.Where(x => x == p).Concat(QuickSort(i.Where(x => x > p))));
}
Get p (pivot) with whatever method is suitable of course.
This is the shortest implementation of Quick Sort algorithm (Without StackOverflowException)
IEnumerable<T> QuickSort<T>(IEnumerable<T> i) where T :IComparable
{
if (!i.Any()) return i;
var p = i.ElementAt(new Random().Next(0, i.Count() - 1));
return QuickSort(i.Where(x => x.CompareTo(p) < 0)).Concat(i.Where(x => x.CompareTo(p) == 0)).Concat(QuickSort(i.Where(x => x.CompareTo(p) > 0)));
}
A Simple Quick Sort Implementation.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/QuickSort.cs
using System;
using System.Collections.Generic;
using System.Linq;
namespace AlgorithmsMadeEasy
{
class QuickSort
{
public void QuickSortMethod()
{
var input = System.Console.ReadLine();
string[] sInput = input.Split(' ');
int[] iInput = Array.ConvertAll(sInput, int.Parse);
QuickSortNow(iInput, 0, iInput.Length - 1);
for (int i = 0; i < iInput.Length; i++)
{
Console.Write(iInput[i] + " ");
}
Console.ReadLine();
}
public static void QuickSortNow(int[] iInput, int start, int end)
{
if (start < end)
{
int pivot = Partition(iInput, start, end);
QuickSortNow(iInput, start, pivot - 1);
QuickSortNow(iInput, pivot + 1, end);
}
}
public static int Partition(int[] iInput, int start, int end)
{
int pivot = iInput[end];
int pIndex = start;
for (int i = start; i < end; i++)
{
if (iInput[i] <= pivot)
{
int temp = iInput[i];
iInput[i] = iInput[pIndex];
iInput[pIndex] = temp;
pIndex++;
}
}
int anotherTemp = iInput[pIndex];
iInput[pIndex] = iInput[end];
iInput[end] = anotherTemp;
return pIndex;
}
}
}
/*
Sample Input:
6 5 3 2 8
Calling Code:
QuickSort qs = new QuickSort();
qs.QuickSortMethod();
*/
Code Implemented with Iteration With last element as Pivot
<code>https://jsfiddle.net/zishanshaikh/5zxvwoq0/3/ </code>
function quickSort(arr,l,u) {
if(l>=u)
{
return;
}
var pivot=arr[u];
var pivotCounter=l;
for(let i=l;i<u;i++)
{
if(arr[i] <pivot )
{
var temp= arr[pivotCounter];
arr[pivotCounter]=arr[i] ;
arr[i]=temp;
pivotCounter++;
}
}
var temp2= arr[pivotCounter];
arr[pivotCounter]=arr[u] ;
arr[u]=temp2;
quickSort(arr,pivotCounter+1,u);
quickSort(arr,0,pivotCounter-1);
}
<code>https://jsfiddle.net/zishanshaikh/exL9cdoe/1/</code>
Code With first element as Pivot
//Logic For Quick Sort
function quickSort(arr,l,u) {
if(l>=u)
{
return;
}
var pivot=arr[l];
var pivotCounter=l+1;
for(let i=l+1;i<u;i++)
{
if(arr[i] <pivot )
{
var temp= arr[pivotCounter];
arr[pivotCounter]=arr[i] ;
arr[i]=temp;
pivotCounter++;
}
}
var j=pivotCounter-1;
var k=l+1;
while(k<=j)
{
var temp2= arr[k-1];
arr[k-1]=arr[k] ;
arr[k]=temp2;
k++;
}
arr[pivotCounter-1]=pivot;
quickSort(arr,pivotCounter,u);
quickSort(arr,0,pivotCounter-2);
}
A simple generic C# implementation of QuickSort, can use first or last value or any other intermediate value for pivot
using System;
namespace QuickSort
{
class Program
{
static void Main(string[] args)
{
int[] arInt = { 6, 4, 2, 8, 4, 5, 4, 5, 4, 5, 4, 8, 11, 1, 7, 4, 13, 5, 45, -1, 0, -7, 56, 10, 57, 56, 57, 56 };
GenericQuickSort<int>.QuickSort(arInt, 0, arInt.Length - 1);
string[] arStr = { "Here", "Is", "A", "Cat", "Really", "Fast", "And", "Clever" };
GenericQuickSort<string>.QuickSort(arStr, 0, arStr.Length - 1); ;
Console.WriteLine(String.Join(',', arInt));
Console.WriteLine(String.Join(',', arStr));
Console.ReadLine();
}
}
class GenericQuickSort<T> where T : IComparable
{
public static void QuickSort(T[] ar, int lBound, int uBound)
{
if (lBound < uBound)
{
var loc = Partition(ar, lBound, uBound);
QuickSort(ar, lBound, loc - 1);
QuickSort(ar, loc + 1, uBound);
}
}
private static int Partition(T[] ar, int lBound, int uBound)
{
var start = lBound;
var end = uBound;
var pivot = ar[uBound];
// switch to first value as pivot
// var pivot = ar[lBound];
while (start < end)
{
while (ar[start].CompareTo(pivot) < 0)
{
start++;
}
while (ar[end].CompareTo(pivot) > 0)
{
end--;
}
if (start < end)
{
if (ar[start].CompareTo(ar[end]) == 0)
{
start++;
}
else
{
swap(ar, start, end);
}
}
}
return end;
}
private static void swap(T[] ar, int i, int j)
{
var temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
}
}
}
Output:
-7,-1,0,1,2,4,4,4,4,4,4,5,5,5,5,6,7,8,8,10,11,13,45,56,56,56,57,57
A,And,Cat,Clever,Fast,Here,Is,Really
One important thing to notice here is that this optimized and simple code properly handles duplicates. I tried several posted quick sort code. Those do not give correct result for this (integer array) input or just hangs, such as https://www.w3resource.com/csharp-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-9.php and http://www.softwareandfinance.com/CSharp/QuickSort_Iterative.html. Therefore, if author also wants to use the code which handles duplicates this would be a good reference.