代码:
using System;
using System.Diagnostics;
namespace ConsoleApp1
{
class Program
{
const int maxResult = 120; //this can change but hardcoded for this code
static int poolPos;
static double[] pool = new double[maxResult * 4];
static int maxPos;
static double[] result = new double[maxResult];
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
for(int i = 0; i < 100_000; ++i)
Unlock();
Console.WriteLine(sw.ElapsedMilliseconds);
//Console.Read();
}
static void Unlock()
{
int total = maxResult;
//reset array
poolPos = 0;
maxPos = 0;
FindLock(4);
while (total-- > 0)
{
int i = 0;
double maxWeight = pool[0];
int pos = 0;
while (++i < poolPos) //O(n), can it be faster?
if (pool[i] >= maxWeight) //can have duplicate value, find latest max inserted
(maxWeight, pos) = (pool[i], i); //keep track
result[maxPos++] = maxWeight; //store the result
pool[pos] = pool[--poolPos]; //remove from array by swapping it with last item in the array
FindLock();
}
}
//simulate what feed the array
//don't look at this unless something should be done at insert time
static Random rnd = new Random(42);
static void FindLock(int add = -1)
{
if(add == -1)
{
add = rnd.Next(1, 4);
}
for(int i = 0;i<add;++i)
{
pool[poolPos++] = rnd.Next(-500, 500) / 100d;
}
}
}
}
基于性能分析,我试图找到一种加快速度的方法,我在网上找到的所有解决方案都使用双栈或双队列,因此它们仅使用数组的头或尾值,上面的代码可以从列表中选择任何符合要求的项目,这样我就不能使用堆栈或队列。
答案 0 :(得分:1)
使用“优先级队列”或“最大堆”,表会部分排序,并且许多操作都是O(log(N)):
已知项目1大于项目2和3。项目1始终是最大值。
已知项目2大于项目4和5。
已知项目3大于项目6和7。
等一般:
已知项目[k]大于项目[2 * k]和[2 * k + 1]。
插入和删除操作比较麻烦,因为您希望保持表格紧凑。
众多参考文献之一:https://www.techiedelight.com/introduction-priority-queues-using-binary-heaps/
如果物品来回频繁,结构可以很方便,但是重要的动作是获取最大值。访问最大值是O(1),但删除最大值是O(N)。
答案 1 :(得分:0)
根据定义,如果您使用的是无序列表,则找到一个项目在最佳情况下始终为O(1),在最坏情况下始终为O(n)。
您可以使用哈希表来获得更好的查找速度以及插入/删除。但是,哈希算法本身可能与遍历列表一样昂贵,因此请谨慎行事。根据使用情况,可以使用哈希表。