using System;
using System.Collections.Generic;
/// <summary>
/// 优先级队列
/// </summary>
namespace EDUtils
{
public class PriorityQueue<T> where T : IComparable<T>
{
public List<T> lst = null;
public int Count { get => lst.Count; }
public PriorityQueue(int capacity = 4)
{
lst = new List<T>(capacity);
}
public void Enqueue(T value)
{
lst.Add(value);
int childIndex = lst.Count - 1;
HeapfiyUp(childIndex);
}
public T Dnqueue()
{
if (lst.Count == 0) return default;
T returnVal = lst[0];
int endIndex = lst.Count - 1;
lst[0] = lst[endIndex];
lst.RemoveAt(endIndex);
--endIndex;
int topIndex = 0;
HeapfiyDown(topIndex, endIndex);
return returnVal;
}
public T Peek()
{
return lst.Count > 0 ? lst[0] : default;
}
public int IndexOf(T item)
{
return lst.IndexOf(item);
}
public T RemoveAt(int rmvIndex)
{
if (lst.Count == rmvIndex) return default;
T returnVal = lst[rmvIndex];
int endIndex = lst.Count - 1;
lst[rmvIndex] = lst[endIndex];
lst.RemoveAt(endIndex);
--endIndex;
if (rmvIndex < endIndex)
{
int parentIndex = (rmvIndex - 1) / 2;
if (parentIndex > 0 && lst[rmvIndex].CompareTo(lst[parentIndex]) < 0)
{
HeapfiyUp(rmvIndex);
}
else
{
HeapfiyDown(rmvIndex, endIndex);
}
}
return returnVal;
}
public T RemoveItem(T item)
{
int index = IndexOf(item);
return index != -1 ? RemoveAt(index) : default;
}
public void Clear()
{
lst.Clear();
}
public bool Contains(T item)
{
return lst.Contains(item);
}
public bool IsEmpty()
{
return lst.Count == 0;
}
public List<T> ToLst()
{
return lst;
}
public T[] ToArr()
{
return lst.ToArray();
}
private void Swap(int indexA, int indexB)
{
T temp = lst[indexA];
lst[indexA] = lst[indexB];
lst[indexB] = temp;
}
void HeapfiyUp(int childIndex)
{
int parentIndex = (childIndex - 1) / 2;
while (childIndex > 0 && lst[childIndex].CompareTo(lst[parentIndex]) < 0)
{
Swap(childIndex, parentIndex);
childIndex = parentIndex;
parentIndex = (childIndex - 1) / 2;
}
}
void HeapfiyDown(int topIndex, int endIndex)
{
while (true)
{
int minIndex = topIndex;
//Left
int childIndex = topIndex * 2 + 1;
if (childIndex <= endIndex && lst[childIndex].CompareTo(lst[topIndex]) < 0)
minIndex = childIndex;
//Right
childIndex = topIndex * 2 + 2;
if (childIndex <= endIndex && lst[childIndex].CompareTo(lst[minIndex]) < 0)
minIndex = childIndex;
if (topIndex == minIndex) break;
Swap(topIndex, minIndex);
topIndex = minIndex;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace EDUtils
{
/// <summary>
/// 小顶堆
/// </summary>
public class Heap
{
public List<int> lst = null;
public Heap(int capacity = 4)
{
lst = new List<int>(capacity);
}
/// <summary>
/// 用整数示例,添加一个节点到堆中
/// </summary>
/// <param name="value"></param>
public void AddNode(int value)
{
lst.Add(value);
int childIndex = lst.Count - 1;
int parentIndex = (childIndex - 1) / 2;
while (childIndex > 0 && lst[childIndex] < lst[parentIndex])
{
Swap(childIndex, parentIndex);
childIndex = parentIndex;
parentIndex = (childIndex - 1) / 2;
}
}
/// <summary>
/// 移除堆顶元素
/// </summary>
/// <returns></returns>
public int RmvNode()
{
if (lst.Count == 0) return int.MinValue;
int returnVal = lst[0];
int endIndex = lst.Count - 1;
lst[0] = lst[endIndex];
lst.RemoveAt(endIndex);
--endIndex;
int topIndex = 0;
while (true)
{
int minIndex = topIndex;
//Left
int childIndex = topIndex * 2 + 1;
if (childIndex <= endIndex && lst[childIndex] < lst[topIndex])
{
minIndex = childIndex;
}
//Right
childIndex = topIndex * 2 + 2;
if (childIndex <= endIndex && lst[childIndex] < lst[minIndex])
{
minIndex = childIndex;
}
if (topIndex==minIndex)
{
break;
}
Swap(topIndex,minIndex);
topIndex = minIndex;
}
return returnVal;
}
private void Swap(int indexA, int indexB)
{
int temp = lst[indexA];
lst[indexA] = lst[indexB];
lst[indexB] = temp;
}
}
}
using EDUtils;
using System;
using System.Diagnostics.CodeAnalysis;
namespace PriorityQueueExample
{
class Program
{
static int[] arr = new int[] { 7, 2, 5, 1, 4, 3 };
static void Main(string[] args)
{
// HeapExample();
QueueExample();
}
static void HeapExample()
{
Heap heap = new Heap(arr.Length);
for (int i = 0; i < arr.Length; i++)
{
heap.AddNode(arr[i]);
}
Console.WriteLine("____________");
for (int i = 0; i < arr.Length; i++)
{
int val = heap.RmvNode();
Console.WriteLine($"Rmv:{val}");
}
Console.ReadKey();
}
static void QueueExample()
{
Item item1 = new Item() { itemName = "1", priority = 7 };
Item item2 = new Item() { itemName = "2", priority = 2 };
Item item3 = new Item() { itemName = "3", priority = 5 };
Item item4 = new Item() { itemName = "4", priority = 1 };
Item item5 = new Item() { itemName = "5", priority = 4 };
Item item6 = new Item() { itemName = "6", priority = 3 };
PriorityQueue<Item> queue = new PriorityQueue<Item>();
queue.Enqueue(item1);
queue.Enqueue(item2);
queue.Enqueue(item3);
queue.Enqueue(item4);
queue.Enqueue(item5);
queue.Enqueue(item6);
while (queue.Count>0)
{
queue.Dnqueue().PrintInfo();
}
Console.WriteLine(">>>>>>>>>>>>>>>>>>>");
}
}
public class Item : IComparable<Item>
{
/// <summary>
/// 名字
/// </summary>
public string itemName;
/// <summary>
/// 优先级
/// </summary>
public float priority;
public int CompareTo(Item other)
{
if (priority < other.priority)
{
return -1;
}
else if (priority > other.priority)
{
return 1;
}
else
{
return 0;
}
}
public void PrintInfo()
{
Console.WriteLine($"itemName:{itemName} priority:{priority}");
}
}
}