using
System;
using
System.Collections.Generic;
public
class
Node
{
public
int
data;
public
Node left, right;
}
public
class
iNPair : IComparable<iNPair>
{
public
int
first;
public
Node second;
public
iNPair(
int
f, Node s)
{
first = f;
second = s;
}
public
int
CompareTo(iNPair other)
{
return
first.CompareTo(other.first);
}
}
class
CartesianTreeSort
{
static
void
pQBasedTraversal(Node root)
{
PriorityQueue<iNPair> pQueue =
new
PriorityQueue<iNPair>();
pQueue.Enqueue(
new
iNPair(root.data, root));
while
(!pQueue.IsEmpty())
{
iNPair poppedPair = pQueue.Dequeue();
Console.Write(poppedPair.first +
" "
);
if
(poppedPair.second.left !=
null
)
pQueue.Enqueue(
new
iNPair(poppedPair.second.left.data, poppedPair.second.left));
if
(poppedPair.second.right !=
null
)
pQueue.Enqueue(
new
iNPair(poppedPair.second.right.data, poppedPair.second.right));
}
Console.WriteLine();
}
static
Node buildCartesianTreeUtil(
int
root,
int
[] arr,
int
[] parent,
int
[] leftChild,
int
[] rightChild)
{
if
(root == -1)
return
null
;
Node temp =
new
Node();
temp.data = arr[root];
temp.left = buildCartesianTreeUtil(leftChild[root], arr, parent, leftChild, rightChild);
temp.right = buildCartesianTreeUtil(rightChild[root], arr, parent, leftChild, rightChild);
return
temp;
}
static
Node buildCartesianTree(
int
[] arr,
int
n)
{
int
[] parent =
new
int
[n];
int
[] leftChild =
new
int
[n];
int
[] rightChild =
new
int
[n];
Array.Fill(parent, -1);
Array.Fill(leftChild, -1);
Array.Fill(rightChild, -1);
int
root = 0, last;
for
(
int
i = 1; i <= n - 1; i++)
{
last = i - 1;
rightChild[i] = -1;
while
(arr[last] >= arr[i] && last != root)
last = parent[last];
if
(arr[last] >= arr[i])
{
parent[root] = i;
leftChild[i] = root;
root = i;
}
else
if
(rightChild[last] == -1)
{
rightChild[last] = i;
parent[i] = last;
leftChild[i] = -1;
}
else
{
parent[rightChild[last]] = i;
leftChild[i] = rightChild[last];
rightChild[last] = i;
parent[i] = last;
}
}
parent[root] = -1;
return
buildCartesianTreeUtil(root, arr, parent, leftChild, rightChild);
}
static
void
printSortedArr(
int
[] arr,
int
n)
{
Node root = buildCartesianTree(arr, n);
Console.WriteLine(
"The sorted array is-"
);
pQBasedTraversal(root);
}
static
void
Main()
{
int
[] arr = { 5, 10, 40, 30, 28 };
int
n = arr.Length;
printSortedArr(arr, n);
}
}
public
class
PriorityQueue<T>
where
T : IComparable<T>
{
private
List<T> data;
public
PriorityQueue()
{
this
.data =
new
List<T>();
}
public
bool
IsEmpty()
{
return
this
.data.Count == 0;
}
public
void
Enqueue(T item)
{
this
.data.Add(item);
int
ci =
this
.data.Count - 1;
while
(ci > 0)
{
int
pi = (ci - 1) / 2;
if
(
this
.data[ci].CompareTo(
this
.data[pi]) >= 0)
break
;
T tmp =
this
.data[ci];
this
.data[ci] =
this
.data[pi];
this
.data[pi] = tmp;
ci = pi;
}
}
public
T Dequeue()
{
int
li =
this
.data.Count - 1;
T frontItem =
this
.data[0];
this
.data[0] =
this
.data[li];
this
.data.RemoveAt(li);
--li;
int
pi = 0;
while
(
true
)
{
int
ci = pi * 2 + 1;
if
(ci > li)
break
;
int
rc = ci + 1;
if
(rc <= li &&
this
.data[rc].CompareTo(
this
.data[ci]) < 0)
ci = rc;
if
(
this
.data[pi].CompareTo(
this
.data[ci]) <= 0)
break
;
T tmp =
this
.data[pi];
this
.data[pi] =
this
.data[ci];
this
.data[ci] = tmp;
pi = ci;
}
return
frontItem;
}
}