using
System;
class
GFG {
const
int
MAX = 1000;
static
void
buildTree(
int
treeIndex,
int
l,
int
r,
int
[] arr,
int
[, ] tree)
{
if
(l == r) {
tree[treeIndex, 0] = arr[l - 1];
return
;
}
int
mid = (l + r) / 2;
buildTree(2 * treeIndex, l, mid, arr, tree);
buildTree(2 * treeIndex + 1, mid + 1, r, arr, tree);
int
i = 0, j = 0;
int
k = 0;
while
(i < tree.GetLength(1)
&& tree[2 * treeIndex, i] != -1
&& j < tree.GetLength(1)
&& tree[2 * treeIndex + 1, j] != -1) {
if
(tree[2 * treeIndex, i]
<= tree[2 * treeIndex + 1, j]) {
tree[treeIndex, k] = tree[2 * treeIndex, i];
i++;
}
else
{
tree[treeIndex, k]
= tree[2 * treeIndex + 1, j];
j++;
}
k++;
}
while
(i < tree.GetLength(1)
&& tree[2 * treeIndex, i] != -1) {
tree[treeIndex, k] = tree[2 * treeIndex, i];
i++;
k++;
}
while
(j < tree.GetLength(1)
&& tree[2 * treeIndex + 1, j] != -1) {
tree[treeIndex, k] = tree[2 * treeIndex + 1, j];
j++;
k++;
}
}
static
int
queryRec(
int
segmentStart,
int
segmentEnd,
int
queryStart,
int
queryEnd,
int
treeIndex,
int
K,
int
[, ] tree)
{
if
(segmentStart == segmentEnd)
return
tree[treeIndex, 0];
int
mid = (segmentStart + segmentEnd) / 2;
int
last_in_query_range = 0;
for
(
int
i = 0; i < tree.GetLength(1); i++) {
if
(tree[2 * treeIndex, i] > queryEnd)
break
;
last_in_query_range++;
}
int
first_in_query_range = 0;
for
(
int
i = 0; i < tree.GetLength(1); i++) {
if
(tree[2 * treeIndex, i] >= queryStart)
break
;
first_in_query_range++;
}
int
M = last_in_query_range - first_in_query_range;
if
(M >= K) {
return
queryRec(segmentStart, mid, queryStart,
queryEnd, 2 * treeIndex, K,
tree);
}
else
{
return
queryRec(mid + 1, segmentEnd, queryStart,
queryEnd, 2 * treeIndex + 1,
K - M, tree);
}
}
static
int
query(
int
queryStart,
int
queryEnd,
int
K,
int
n,
int
[] arr,
int
[, ] tree)
{
return
queryRec(1, n, queryStart, queryEnd, 1, K,
tree);
}
static
int
quickSortComparisons(
int
start,
int
end,
int
n,
int
[] arr,
int
[, ] tree)
{
if
(start >= end)
return
0;
int
middlePoint = (end - start + 2) / 2;
int
pivot
= query(start, end, middlePoint, n, arr, tree);
int
comparisons_in_parent = (end - start + 1);
int
comparisons_in_left_part = quickSortComparisons(
start, pivot - 1, n, arr, tree);
int
comparisons_in_right_part
= quickSortComparisons(pivot + 1, end, n, arr,
tree);
return
comparisons_in_left_part
+ comparisons_in_parent
+ comparisons_in_right_part;
}
static
public
void
Main()
{
int
[] arr = { 4, 3, 5, 1, 2 };
int
n = arr.Length;
int
[, ] tree =
new
int
[MAX, MAX];
for
(
int
i = 0; i < MAX; i++)
for
(
int
j = 0; j < MAX; j++)
tree[i, j] = -1;
buildTree(1, 1, n, arr, tree);
Console.Write(
"Number of Comparisons = "
);
Console.Write(
quickSortComparisons(1, n, n, arr, tree));
}
}