using
System;
using
System.Collections.Generic;
public
class
Node
{
public
int
data;
public
Node next;
public
Node(
int
data)
{
this
.data = data;
this
.next =
null
;
}
}
public
class
Program
{
public
static
List<
int
> FindNLargestElements(Node head,
int
N)
{
var
pq =
new
PriorityQueue<
int
>((x, y) => y.CompareTo(x));
while
(head !=
null
)
{
pq.Enqueue(head.data);
head = head.next;
}
var
result =
new
List<
int
>();
for
(
int
i = 0; i < N; i++)
{
if
(pq.Count > 0)
{
result.Add(pq.Dequeue());
}
}
return
result;
}
public
static
void
Print(List<
int
> list)
{
foreach
(
var
num
in
list)
{
Console.Write(num +
" "
);
}
Console.WriteLine();
}
public
static
void
InsertAtTheBegin(
ref
Node head,
int
data)
{
var
newNode =
new
Node(data);
newNode.next = head;
head = newNode;
}
public
static
void
Main()
{
int
[] arr = { 81, 52, 45, 10, 3, 2, 96 };
int
N = 3;
Node start =
null
;
for
(
int
i = arr.Length - 1; i >= 0; i--)
{
InsertAtTheBegin(
ref
start, arr[i]);
}
var
result = FindNLargestElements(start, N);
Console.Write(
"Output: "
);
Print(result);
}
}
public
class
PriorityQueue<T>
where
T : IComparable<T>
{
private
List<T> data;
private
Comparison<T> comparison;
public
PriorityQueue(Comparison<T> comparison)
{
this
.data =
new
List<T>();
this
.comparison = comparison;
}
public
void
Enqueue(T item)
{
data.Add(item);
int
childIndex = data.Count - 1;
while
(childIndex > 0)
{
int
parentIndex = (childIndex - 1) / 2;
if
(comparison(data[childIndex], data[parentIndex]) >= 0)
break
;
T tmp = data[childIndex];
data[childIndex] = data[parentIndex];
data[parentIndex] = tmp;
childIndex = parentIndex;
}
}
public
T Dequeue()
{
int
lastIndex = data.Count - 1;
T frontItem = data[0];
data[0] = data[lastIndex];
data.RemoveAt(lastIndex--);
int
parentIndex = 0;
while
(
true
)
{
int
leftChildIndex = parentIndex * 2 + 1;
if
(leftChildIndex > lastIndex)
break
;
int
rightChildIndex = leftChildIndex + 1;
if
(rightChildIndex <= lastIndex && comparison(data[rightChildIndex], data[leftChildIndex]) < 0)
leftChildIndex = rightChildIndex;
if
(comparison(data[parentIndex], data[leftChildIndex]) <= 0)
break
;
T tmp = data[parentIndex];
data[parentIndex] = data[leftChildIndex];
data[leftChildIndex] = tmp;
parentIndex = leftChildIndex;
}
return
frontItem;
}
public
int
Count
{
get
{
return
data.Count; }
}
}