I wrote a simple implementation of a b-tree, and the problem is that it is too slow (tl9 on codeforces). What should i change to speed up this tree?
The memory limit problem can be easily fixed by increasing the constant b, but then there are time limit problems.
class BtreeSimple
{
public Bnode root = new Bnode(true);
private static int counter;
public void Add(int key)
{
var (overkey, overflow, overvalue) = root.Insert(key, counter);
counter++;
if (overflow == null)
return;
root = new Bnode(false) {Count = 1, Keys = {[0] = overkey}, Vals = {[0] = overvalue}, Kids = {[0] = root, [1] = overflow}};
}
}
class Bnode
{
const int b = 16;
public int Count;
public int[] Keys = new int[2 * b + 1];
public Bnode[] Kids;
public Bnode(bool leaf) => Kids = leaf ? null : new Bnode[2 * b + 2];
public int[] Vals = new int[2 * b + 1];
public (int, Bnode, int) Insert(int key, int value)
{
var i = GetKeyPosition(key);
if (Kids == null) return InsertAt(i, key, null, value);
var (overkey, overflow, overvalue) = Kids[i].Insert(key, value);
return overflow == null ? (0, null, 0) : InsertAt(i, overkey, overflow, overvalue);
}
private int GetKeyPosition(int key)
{
var i = 0;
while (i < Count && Keys[i] < key)
i++;
return i;
}
private (int, Bnode, int) InsertAt(int i, int key, Bnode keyNode, int value)
{
Array.Copy(Keys, i, Keys, i + 1, Count - i);
Keys[i] = key;
Vals[i] = value;
if (keyNode != null)
{
Array.Copy(Kids, i + 1, Kids, i + 2, Count - i);
Kids[i + 1] = keyNode;
}
return ++Count <= 2 * b ? (0, null, 0) : Split();
}
private (int, Bnode, int) Split()
{
var split = new Bnode(Kids == null) { Count = b };
Array.Copy(Keys, b + 1, split.Keys, 0, b);
Array.Copy(Vals, b + 1, split.Vals, 0, b);
if (Kids != null)
Array.Copy(Kids, b + 1, split.Kids, 0, b + 1);
Count = b;
return (Keys[b], split, Vals[b]);
}
public int FindNearest(int key)
{
var i = GetKeyPosition(key);
if (Keys[i] == key)
return Vals[i];
if (Kids != null)
return Kids[i].FindNearest(key);
if (i >= Count)
return Vals[i - 1]+1;
if (Keys[i] < key)
return Vals[i] + 1;
return Vals[i];
}
}
We have a sorted array (for example arr = [8, 9, 10, 11, 15, 17, 20]) and keys (for example keys = [7, 10, 21, 20]). The task is to tell how many keys from arr are less than keys[i] for each i. For this purpose I made a methdod "FindNearest".
Everything else in the code is just pure b-tree.
Related
I'm trying to compile the below code: (normally get and set operation)
please assist with reviewing the insertion sort function, all the rest compiling perfectly.
The return value comparing 2 cells only (and it's correct).
any idea what can cause that?
private static void Main()
{
IArray<int?> arr = Read();
Console.WriteLine(arr);
SelectionSort(arr);
Console.WriteLine(arr);
if (arr.Length >= 2)
{
arr.Set(arr.Length - 2, null);
Console.WriteLine(arr);
}
if (arr.Length >= 1)
{
arr.Set(arr.Length - 1, null);
Console.WriteLine(arr);
}
SelectionSort(arr);
Console.WriteLine(arr);
Console.WriteLine("(" + arr.Get(100) + ")");
Console.WriteLine("insertion sort");
int n = arr.Length;
Insertionsort(arr, n);
Console.WriteLine(arr);
//// throw exception
//_ = new DynArr<int>();
}
private static IArray<int?> Read()
{
var arr = new DynArr<int?>();
Console.Write("Enter size >> ");
var size = int.Parse(Console.ReadLine().Trim());
for (var i = 0; i < size; ++i)
{
Console.Write("Enter [" + i + "] >> ");
arr.Set(i, int.Parse(Console.ReadLine().Trim()));
}
return arr;
}
}
private static void Insertionsort(IArray<int?> arr, int n)
{
for (int i = 1; i < n; i++)
{
var j = i - 1;
voidcompare(arr, i, j);
}
}
private static void voidcompare(IArray<int?> arr, int i, int j)
{
var c = arr.Get(i);
while (j >= 0 && arr.Get(j) > c)
{
arr.Set(j + 1, c);
}
}
}
}
Your Sort alg. isn't corect. See hier how it's working - Insertion Sort. Bellow i provide you a possible implementation.
public class Program
{
static void Main()
{
var collection = new List<int?> { 25, 71, 43, -1, 15, 0, 38 };
DoInsertionSort(collection, collection.Count);
Console.WriteLine(string.Join(Environment.NewLine, collection));
}
static void DoInsertionSort(IList<int?> collection, int length)
{
if (collection is null || collection.Count == 0 || length <= 0 || length > collection.Count)
{
return;
}
var previous = default(int?);
for (int index = 0; index < length; index++)
{
var current = collection.Get(index);
if (current < previous)
{
SwapUpToStart(collection, current, index);
}
previous = collection.Get(index);
}
}
private static void SwapUpToStart(IList<int?> collection, int? current, int currentIndex)
{
for (int index = currentIndex - 1; index >= 0; index--)
{
var previous = collection.Get(index);
if (current >= previous)
{
break;
}
collection.Swap(index, current, previous);
}
}
}
public static class YourIArray_T_Implementation
{
public static int? Get(this IList<int?> collection, int index)
{
return collection[index];
}
public static void Swap(this IList<int?> collection, int index, int? current, int? previous)
{
collection[index] = current;
collection[index + 1] = previous;
}
}
I am trying to figure out how to find and delete max number in list. (I am not allowed to use Dictionary, List, LinkedList, SortedList and similar ones).
The list of numbers is converted to array { 1055, 2, 29, 8, 7, 2000, 29, 8, 22, 6, 29, } the "s" is the list.
I am able to find the highest number in list and I feel like the code for deleting it is also correct but the problem is the way it works in my head is 1st loop to find the highest number:
int tmp = 0;
while (s != null)
{
if(tmp < s.data)
{
tmp = s.data;
}
s = s.next;
}
Console.WriteLine(tmp);
return null;
This will correctly return me 2000.
And 2nd loop should basically move to the next number so the highest one does not show.
while (s != null)
{
if (s.data == tmp)
{
s = s.next;
}
Console.Write(s.data + " ");
s = s.next;
}
I tried to play around with the loops but cant find out how to combine this together to make it work.
Thank you for any advice. I am open to a different approach.
Adding all relevant code to the case
class Seznam
{
public int data;
public Seznam next;
public Seznam prev;
static void Main(string[] args)
{
int[] pole = { 1055, 2, 29, 8, 7, 2000, 29, 8, 22, 6, 29, };
Seznam s = convertArray(pole); //This is the list
s = DeleteMax(s);
Console.ReadLine();
}
static Seznam DeleteMax(Seznam s)
{
int tmp = 0;
while (s != null)
{
if(tmp < s.data)
{
tmp = s.data;
}
s = s.next;
}
Console.WriteLine(tmp);
return null;
}
}
public static void DeleteMax(Seznam s)
{
int tmp = 0;
Seznam max = s;
while (s != null)
{
if (tmp < s.data)
{
tmp = s.data;
max = s;
}
s = s.next;
}
if (max != null)
{
max.prev.next = max.next;
max.next.prev = max.prev;
}
}
If you would use another variable then you could save a counter to know where is the highest num located in the array.
Just like this:
int tmp = 0;
int location = 0;
int counter = 0;
while (s != null)
{
if (tmp < s.data)
{
tmp = s.data;
location = counter;
}
s = s.next;
counter = counter + 1;
}
Console.WriteLine(tmp);
return null;
After that you can find that one and remove it easily.
Was wondering how can I convert an int to a List in reverse order padded with zeroes and vice versa?
Have a byte that represents List(8), sometimes 2 bytes for List(16), 8 bytes for List(64); so looking for a good solution to handle converting to an int list, manipulate then back again.
e.g. Input of 3 to a List of 1,1,0,0,0,0,0,0
Or input of 42 to a List of 0,1,0,1,0,1,0,0
And vice-versa, take a List of 1,1,0,0,0,0,0,0 and return 3 or List of 0,1,0,1,0,1,0,0 and return 42
What I have done at present is build a couple of functions to handle both scenarios, all works fine, just wondering if there is a better / more elegant solution that I've completelt overlooked?
private List<int> IntToList(int _Input)
{
string _Binary = ReverseString(Convert.ToString(_Input, 2).PadLeft(8, '0'));
List<int> _List = new List<int>(8);
for (int i = 0; i < _Binary.Length; i++)
{
_List.Add(Convert.ToInt32(_Binary.Substring(i, 1)));
}
return _List;
}
private int IntsToByte(List<int> _List)
{
string _Binary = "";
for (int i = 7; i > -1; i--)
{
_Binary += _List[i];
}
return Convert.ToInt32(_Binary, 2);
}
You can work with bitwise operations. They might be fast.
Warning : Be aware of Little/Big Endian (More here)
The following code works :
private List<int> IntToList(int _Input, int _MaxSize = 8)
{
int padding = 1;
List<int> resultList = new List<int>(_MaxSize);
while (padding < 1 << _MaxSize)
{
resultList.Add((_Input & padding) == padding ? 1 : 0);
padding = padding << 1;
}
return resultList;
}
private int IntsToByte(List<int> _List)
{
int result = 0, padding = 0;
foreach (int i in _List)
{
result = result | (i << padding++);
}
return result;
}
This should work
int number = 42
char[] reverse = Convert.ToString(number, 2).PadLeft(8, '0').ToCharArray();
Array.Reverse(reverse);
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<ulong> results = null;
List<byte> output = null;
List<byte> input1 = new List<byte>() { 1, 1, 0, 0, 0, 0, 0, 0 };
results = ReadList(input1, 1);
output = WriteList(results,1);
List<byte> input2 = new List<byte>() { 0, 1, 0, 1, 0, 1, 0, 0 };
results = ReadList(input2, 1);
output = WriteList(results,1);
}
static List<ulong> ReadList(List<byte> input, int size)
{
List<ulong> results = new List<ulong>();
input.Reverse();
MemoryStream stream = new MemoryStream(input.ToArray());
BinaryReader reader = new BinaryReader(stream);
int count = 0;
ulong newValue = 0;
while (reader.PeekChar() != -1)
{
switch (size)
{
case 1:
newValue = ((ulong)Math.Pow(2, size) * newValue) + (ulong)reader.ReadByte();
break;
case 2:
newValue = ((ulong)Math.Pow(2, size) * newValue) + (ulong)reader.ReadInt16();
break;
}
if (++count == size)
{
results.Add(newValue);
newValue = 0;
count = 0;
}
}
return results;
}
static List<byte> WriteList(List<ulong> input, int size)
{
List<byte> results = new List<byte>();
foreach (ulong num in input)
{
ulong result = num;
for (int count = 0; count < size; count++)
{
if (result > 0)
{
byte bit = (byte)(result % Math.Pow(2, size));
results.Add(bit);
result = (ulong)(result / Math.Pow(2, size));
}
else
{
results.Add(0);
}
}
}
results.Reverse();
return results;
}
}
}
Solution from OP.
Have gone with Jean Bob's suggestion of using BitWise.
For anyone elses benefit, here is my modified version to read / write in blocks of 8 to/from the list.
private List<int> IntToList(List<int> _List, int _Input)
{
int _Padding = 1;
while (_Padding < 1 << 8)
{
_List.Add((_Input & _Padding) == _Padding ? 1 : 0);
_Padding = _Padding << 1;
}
return _List;
}
private int IntsToByte(List<int> _List, int l)
{
int _Result = 0, _Padding = 0;
for (int i = l; i < (l + 8); i++)
{
_Result = _Result | (_List[i] << _Padding++);
}
return _Result;
}
as all newbies to the searching algorithms, i am working on an example of the old fashion 8-problem puzzle, i have done the breadth first algorithm which is in the code below, and i was wondering how can convert it to the depth first limited search.
how can I convert from the breadth first algorithm to the depth first limited search algorithm??
code :
class BFS
{
int[] GoalState = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
private Queue<Node> Frontier;
private HashSet<Node> Solution;
private Node RootNode;
public BFS(int[] StartState)
{
this.RootNode = new Node(StartState, -1, "\0");
Solution = new HashSet<Node>();
Frontier = new Queue<Node>();
}
public void Solve()
{
Node ActiveNode = RootNode;
bool IsSolved = false;
while (!IsGoalState(ActiveNode.GetState()))
{
Solution.Add(ActiveNode);
foreach (Node successor in GenerateSuccessor(ActiveNode))
{
Frontier.Enqueue(successor);
if (IsGoalState(successor.GetState()))
{
IsSolved = true;
Solution.Add(successor);
break;
}
}
if (IsSolved)
break;
ActiveNode = Frontier.Dequeue();
}
WriteSolution();
}
public IEnumerable<Node> GenerateSuccessor(Node ParentNode)
{
int[] ParentState = ParentNode.GetState();
int EmptySpacePosition = 0;
int temp;
for (int x = 0; x < 9; x++)
{
if (ParentState[x] == 0)
{
EmptySpacePosition = x;
break;
}
}
//Can move empty space to LEFT?
if (EmptySpacePosition != 0 && EmptySpacePosition != 3 && EmptySpacePosition != 6)
{
int[] _State = (int[])ParentState.Clone();
_State[EmptySpacePosition] = _State[EmptySpacePosition - 1];
_State[EmptySpacePosition - 1] = 0;
yield return new Node(_State, ParentNode.GetId(), "Left ");
}
//Can move empty space to RIGHT?
if (EmptySpacePosition != 2 && EmptySpacePosition != 5 && EmptySpacePosition != 8)
{
int[] _State = (int[])ParentState.Clone();
_State[EmptySpacePosition] = _State[EmptySpacePosition + 1];
_State[EmptySpacePosition + 1] = 0;
yield return new Node(_State, ParentNode.GetId(),"Right ");
}
//Can move empty space to UP?
if (EmptySpacePosition > 2)
{
int[] _State = (int[])ParentState.Clone();
_State[EmptySpacePosition] = _State[EmptySpacePosition - 3];
_State[EmptySpacePosition - 3] = 0;
yield return new Node(_State, ParentNode.GetId(), "Up ");
}
//Can move empty space to DOWN?
if (EmptySpacePosition < 6)
{
int[] _State = (int[])ParentState.Clone();
_State[EmptySpacePosition] = _State[EmptySpacePosition + 3];
_State[EmptySpacePosition + 3] = 0;
yield return new Node(_State, ParentNode.GetId(),"Down ");
}
}
public bool IsGoalState(int[] State)
{
for (int x = 0; x < 9; x++)
{
if (State[x] != GoalState[x])
return false;
}
return true;
}
public void WriteSolution()
{
StringBuilder s = new StringBuilder();
int ParentId = 0;
#region InfoPrint
Console.Write("Puzzle= ");
foreach (int i in RootNode.GetState())
{
Console.Write(i);
}
Console.WriteLine();
Console.WriteLine("Nodes Generated= " + (Solution.Count + Frontier.Count));
#endregion
foreach (Node n in Solution.Reverse())
{
if (ParentId == 0 || n.GetId() == ParentId)
{
s.Append(n.GetMove());
ParentId = n.GetParentId();
}
}
Console.WriteLine("Solution Length= " + (s.Length - 1));
Console.WriteLine("Solution= " + s.ToString());
}
}
and here is my class node
class Node
{
static int _IdCnt = 0;
private int[] State;
private int Id;
private int ParentId;
private string Move;
public Node(int[] State, int ParentId, string Move)
{
Id = _IdCnt++;
this.State = State;
this.ParentId = ParentId;
this.Move = Move;
}
public void SetState(int[] State)
{
this.State = State;
}
public int[] GetState()
{
return (int[])State.Clone();
}
public int GetId()
{
return Id;
}
public int GetParentId()
{
return ParentId;
}
public string GetMove()
{
return Move;
}
}
In the DFS, you'll need to use stack instead of queue. Basically, you add the root node to a stack, and while stack contains a node, you pop the node, do your logic, add its neighbors to the stack and continue.
1. Add root to a stack.
2. while(stack.Count > 0)
{
3. pop the stack
4. if matches, return
5. else add neighbors to stack
}
return not found
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.