C# 自定义二进制堆的顺序并不总是正确的
我创建了一个C# 自定义二进制堆的顺序并不总是正确的,c#,.net,algorithm,data-structures,C#,.net,Algorithm,Data Structures,我创建了一个二进制堆类 public class BinaryHeap<T> { private List<T> _heap; // Constructor public BinaryHeap(int capacity, IComparer<T> comparer) { this._heap = new List<T>(capacity); Comparer = comparer ?
二进制堆
类
public class BinaryHeap<T>
{
private List<T> _heap;
// Constructor
public BinaryHeap(int capacity, IComparer<T> comparer)
{
this._heap = new List<T>(capacity);
Comparer = comparer ?? Comparer<T>.Default;
}
// Constructor
public BinaryHeap(int capacity) : this(capacity, (IComparer<T>)null) { }
// Gets/sets IComparer
public IComparer<T> Comparer { get; private set; }
// Gets/sets the capacity
public int Capacity
{
get { return this._heap.Capacity; }
set { this._heap.Capacity = value; }
}
// Gets the number of elements
public int Count
{
get { return this._heap.Count; }
}
// Inserts the specified element within this BinaryHeap.
public void Insert(T element)
{
// Add the element as the last element.
this._heap.Add(element);
// Index of last added element.
int last = this._heap.Count - 1;
int parent;
T swap;
while (last > 0)
{
parent = (last - 1) >> 1; // parent(i) = (i-1)/2
if (Comparer.Compare(this._heap[parent], this._heap[last]) <= 0)
break; // exit while if the current node is lesser than its parent.
swap = this._heap[last]; // If the parent is greater
this._heap[last] = this._heap[parent]; // than the current node,
this._heap[parent] = swap; // then swap them.
last = parent; // Updates index of last added element.
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public T Remove()
{
if (this._heap.Count > 0)
{
// Save the element.
T result = this._heap[0];
int lastIndex = this._heap.Count - 1; // The last element moves
this._heap[0] = this._heap[lastIndex]; // moves to the root
this._heap.RemoveAt(lastIndex); // of this tree.
lastIndex--; // Update position of last element.
int i = 0; // Position of moved node.
while (i < lastIndex)
{
int minIndex = i;
int left = (i << 1) + 1; // left(i) = (i*2)+1
if (left < lastIndex && Comparer.Compare(this._heap[left], this._heap[minIndex]) < 0)
{
minIndex = left;
}
int right = left + 1; // right(i) = (i*2)+2
if (right < lastIndex && Comparer.Compare(this._heap[right], this._heap[minIndex]) < 0)
{
minIndex = right;
}
if (minIndex != i)
{
// If one of the two children is lesser than the parent,
// then swap the latter with the lesser child.
T temp = this._heap[i];
this._heap[i] = this._heap[minIndex];
this._heap[minIndex] = temp;
i = minIndex;
}
else break;
}
// Return the minimum element that has been removed.
return result;
}
else throw new InvalidOperationException("BinaryHeap is empty.");
}
}
测试多个计数
值时,此问题并不总是发生。
为什么?
如何解决此问题?该症状表示Remove()方法中存在问题
您的
lastIndex
var指向最后一项,因此在minIndex的2次计算中,您应该使用更适合@L.B-不,这里有一个实际问题。非常适合这样。我应该在上面写同样的问题吗?当然不是在任何元站点上,也不要交叉发布。请稍等,如果有足够多的人同意LB,该职位将被移动。既然这个问题似乎已经解决了,那就别管它了。我不得不用if(leftif(left
BinaryHeap<int> q = new BinaryHeap<int>(0);
int count = 50;
for (int i = 0; i < count; i++)
q.Insert(i);
for (int i = 0; i < count; i++)
Console.WriteLine(q.Remove());
Console.ReadLine();
// previous element are in correct order
44
45
46
48 // wrong order
47 // wrong order
49
// if (left < lastIndex && ...)
if (left <= lastIndex && ...)