我有一堆性能问题。我不知道我的代码的哪一部分会影响这个数据结构的性能。例如插入/删除9999个元素需要12000毫秒。堆必须在100ms内完成(理论上)。普通列表在20000毫秒内完成。你能指出我在代码中使用过的一些坏习惯吗?堆性能低下。 O(n)而不是t O(日志n)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Heap
{
int[] items;
int size = 1;
public Heap()
{
items = new int[size];
}
public Heap(int size)
{
items = new int[size];
}
public void AddOnLast(int value)
{
int i = items.Length + 1;
Array.Resize(ref items, i);
items[items.Length-1] = value;
}
// Deleting item of specific index from the array/ using LINQ
public void RemoveAt(int indexToRemove)
{
items = items.Where((source, indexOfElements) => indexOfElements != indexToRemove).ToArray();
}
/*Method which push up the elment after adding it on the last place
k - last index/ when k=0, element is on the top of the heap
p - parent index/ item - value of element/ parent - value of parent */
private void PushUp()
{
int k = items.Length - 1;
while (k > 0)
{
int p = (k - 1)/2;
int item = items[k];
int parent = items[p];
if (item > parent)
{
//Swap of elements
items[k] = parent;
items[p] = item;
k = p;
}
else
{
break;
}
}
}
// Method which put element in correct place of the heap
public void insert(int value)
{
AddOnLast(value);
PushUp();
}
/* After deleting item from the heap we have to push down element to check if heap structure is correct
k - index of first element, top of the heap/ l - left "child" index/r - right child index
max is max value - either right or left child */
private void PushDown()
{
int k = 0;
int l = 2 * k + 1;
while (l < items.Length)
{
int max = 1;
int r = l + 1;
if (r < items.Length)
{
if (items[r] > items[l])
{
//max become right child
max++;
}
}
if (items[k] < items[max])
{
//swap of 2 values, prevous element and next element are swapped
int temp = items[k];
items[k] = items[max];
items[max] = temp;
}
else
{
break;
}
}
}
//Deleting item from the top of the heap
public void delete()
{
if (items.Length == 0)
{
Console.Write("No elements to delete");
}
else if (items.Length == 1)
{
RemoveAt(0);
}
else
{
int hold = items[0];// we hold the first element
items[0] = items[items.Length - 1]; // last element become first
RemoveAt(items.Length - 1); // we delete last element, and check if last element which is now on the top of the heap is on the right place
PushDown();
}
}
}
在'RemoveAt'方法的线条看上去非常昂贵。您每次都重新分配一个新阵列。 – GolfWolf
对我来说这将是非常艰难的替换它:(但感谢您的关注,我希望其他提示 – davoid
也调整AddOnLast是不是免费的使用大数组,只改变索引当你填充它,调整它的大小例如要大一倍 –