using System;
using System.Collections.Generic;
using System.Text;
namespace Collections
{
///
/// 優先度付き待ち行列
///
/// 要素の型
class PriorityQueue
where T : IComparable
{
#region フィールド
ArrayList buffer;
#endregion
#region 初期化
public PriorityQueue() { this.buffer = new ArrayList(); }
public PriorityQueue(int capacity) { this.buffer = new ArrayList(capacity); }
#endregion
#region ヒープ操作
///
/// ヒープ化されている配列リストに新しい要素を追加する。
///
/// 対象の配列リスト
static void PushHeap(ArrayList array, T elem)
{
int n = array.Count;
array.InsertLast(elem);
while (n != 0)
{
int i = (n - 1) / 2;
if (array[n].CompareTo(array[i]) > 0)
{
T tmp = array[n]; array[n] = array[i]; array[i] = tmp;
}
n = i;
}
}
///
/// ヒープから最大値を削除する。
///
/// 対象の配列リスト
static void PopHeap(ArrayList array)
{
int n = array.Count - 1;
array[0] = array[n];
array.EraseLast();
for (int i = 0, j; (j = 2 * i + 1) < n; )
{
if ((j != n - 1) && (array[j].CompareTo(array[j + 1]) < 0))
j++;
if (array[i].CompareTo(array[j]) < 0)
{
T tmp = array[j]; array[j] = array[i]; array[i] = tmp;
}
i = j;
}
}
#endregion
#region 要素の挿入・削除
///
/// 要素のプッシュ。
///
/// 挿入したい要素
public void Push(T elem)
{
PushHeap(this.buffer, elem);
}
///
/// 要素を1つポップ。
///
///
/// 今回の実装では、先頭要素の読み出しと削除は別に行う。
/// この Pop では削除のみ。
/// 読み出しには Top プロパティを使う。
///
public void Pop()
{
PopHeap(this.buffer);
}
///
/// 先頭要素の読み出し。
///
public T Top
{
get { return this.buffer[0]; }
}
public int Count
{
get { return this.buffer.Count; }
}
#endregion
}
}