using
System;
using
System.Collections.Generic;
class
MainClass {
class
Heap {
public
List<
int
> v;
public
int
n;
public
Heap(
int
i = 0) {
n = i;
v =
new
List<
int
>(n);
}
}
static
int
Left(
int
i) {
return
2 * i + 1; }
static
int
Right(
int
i) {
return
2 * i + 2; }
static
int
KthGreatest(Heap h,
int
k) {
PriorityQueue<Tuple<
int
,
int
>> p =
new
PriorityQueue<Tuple<
int
,
int
>>(Comparer<Tuple<
int
,
int
>>.Create((t1, t2) => t2.Item1.CompareTo(t1.Item1)));
p.Enqueue(Tuple.Create(h.v[0], 0));
for
(
int
i = 0; i < k - 1; ++i) {
Tuple<
int
,
int
> tuple = p.Dequeue();
int
j = tuple.Item2;
int
l = Left(j), r = Right(j);
if
(l < h.n)
p.Enqueue(Tuple.Create(h.v[l], l));
if
(r < h.n)
p.Enqueue(Tuple.Create(h.v[r], r));
}
return
p.Peek().Item1;
}
public
static
void
Main(
string
[] args) {
Heap h =
new
Heap(7);
h.v =
new
List<
int
> { 20, 15, 18, 8, 10, 5, 17 };
int
k = 2;
Console.WriteLine(KthGreatest(h, k));
}
class
PriorityQueue<T> {
private
List<T> data;
private
IComparer<T> comparer;
public
PriorityQueue(IComparer<T> comparer =
null
) {
this
.data =
new
List<T>();
this
.comparer = comparer ?? Comparer<T>.Default;
}
public
void
Enqueue(T item) {
data.Add(item);
int
childIndex = data.Count - 1;
while
(childIndex > 0) {
int
parentIndex = (childIndex - 1) / 2;
if
(comparer.Compare(data[childIndex], data[parentIndex]) >= 0) {
break
;
}
Swap(childIndex, parentIndex);
childIndex = parentIndex;
}
}
public
T Dequeue() {
int
lastIndex = data.Count - 1;
T frontItem = data[0];
data[0] = data[lastIndex];
data.RemoveAt(lastIndex);
--lastIndex;
int
parentIndex = 0;
while
(
true
) {
int
leftChild = parentIndex * 2 + 1;
if
(leftChild > lastIndex) {
break
;
}
int
rightChild = leftChild + 1;
if
(rightChild <= lastIndex &&
comparer.Compare(data[rightChild], data[leftChild]) < 0) {
leftChild = rightChild;
}
if
(comparer.Compare(data[parentIndex], data[leftChild]) <= 0) {
break
;
}
Swap(parentIndex, leftChild);
parentIndex = leftChild;
}
return
frontItem;
}
public
T Peek() {
T frontItem = data[0];
return
frontItem;
}
public
int
Count() {
return
data.Count;
}
private
void
Swap(
int
index1,
int
index2) {
T temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
}
}