-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPriorityQueue.cs
More file actions
87 lines (77 loc) · 1.93 KB
/
Copy pathPriorityQueue.cs
File metadata and controls
87 lines (77 loc) · 1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
namespace PriorityQueue;
public class PriorityQueue<T> where T : IComparable<T>
{
private int Count { get; set; } = 0;
private readonly IList<T> _arr;
public bool IsEmpty => Count == 0;
/// <summary>
/// O(N)构造
/// </summary>
public PriorityQueue(IList<T> arr)
{
_arr = arr;
Count = arr.Count;
for (var i = (Count - 1) >> 1; i >= 0; i--)
Down(i);
}
/// <summary>
/// O(NlogN)构造
/// </summary>
// public PriorityQueue(IList<T> arr)
// {
// _arr = new List<T>(arr.Count);
// foreach (var item in arr)
// Push(item);
// }
private void Push(T item)
{
InnerAdd(item);
Up(Count - 1, item);
}
public T Pop()
{
if (IsEmpty)
throw new InvalidOperationException("IsEmpty!");
var ret = _arr[0];
_arr[0] = _arr[Count - 1];
InnerRemove();
Down(0);
return ret;
}
private void Up(int child, T item)
{
for (int parent = (child - 1) >> 1; parent >= 0; parent = (child - 1) >> 1)
{
if (_arr[parent].CompareTo(item) < 0)
_arr[child] = _arr[parent];
else
break;
child = parent;
}
_arr[child] = item;
}
private void Down(int parent)
{
var temp = _arr[parent];
for (int child = (parent << 1) + 1; child < Count; child = (parent << 1) + 1)
{
if (child + 1 < Count && _arr[child + 1].CompareTo(_arr[child]) > 0)
++child;
if (_arr[child].CompareTo(temp) > 0)
_arr[parent] = _arr[child];
else
break;
parent = child;
}
_arr[parent] = temp;
}
private void InnerAdd(T item)
{
_arr.Add(item);
++Count;
}
private void InnerRemove()
{
--Count;
}
}