查找前K大之O(N)算法,千万中找前1000数据不到300毫秒。

 随便写的,速度可能不是最优,但是已经是O(n)了。实际使用时候可能受其他设备和程序输出速度限制,这里是模拟的数据。

思路是保持前K大有序,然后插入时候判断,非大不插,并且插入的时候是二分查找位置,弹出最后一个。

以后有空再研究下最大堆的插入和维持,这个先放这里放着吧。因为N*(LogK+C)还是常数*N,所以认为复杂度依然是O(N).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication5
{
class Program
{

static void Main(string[] args)
{
MaxHeap
<KV> myKV = new MaxHeap<KV>(1000);
Random Rand
= new Random();
Stopwatch sw
= new Stopwatch();
sw.Start();
for (int i = 0; i < 1000*1000; i++)
{
KV iterm
= new KV(i.ToString(), Rand.Next(1000));
//Console.WriteLine("第" + (i + 1) + "次插入:“" + iterm.Key + "”," + iterm.Value);
myKV.Insert(iterm);
}
sw.Stop();
//Show(myKV);
Console.WriteLine(sw.ElapsedMilliseconds);
Console.Read();
}
static void Show(MaxHeap<KV> heap)
{
for (int i = 0; i < heap.Heap.Length; i++)
{
KV iterm
= heap.Heap[i];
string result = (iterm == null) ? "Null" : "\"" + iterm.Key + "\"," + iterm.Value;
Console.WriteLine(result);
}
Console.WriteLine(
"长度:" + heap.Count + "-------------------------------");
}

public class KV : IComparable<KV>
{
public string Key;
public int Value;
public KV(string key, int value)
{
Key
= key;
Value
= value;
}
public int CompareTo(KV x)
{
if (x == null)
{
return 1;
}
if (this.Value == x.Value)
{
return this.Key.CompareTo(x.Key);
}
else
{
return this.Value.CompareTo(x.Value);
}
}
}
public class MaxHeap<T> where T : IComparable<T>
{
private int heapSize = 0;
public T[] Heap;
public int Count = 0;
public MaxHeap(int size)
{
heapSize
= size;
Heap
= new T[size];
}
public void Insert(T iterm)
{
if (iterm.CompareTo(Heap[heapSize - 1]) > 0)
{
Insert(iterm,
0, (Heap.Length - 1) / 2, Heap.Length - 1);
}
Count
++;
}

private void Insert(T iterm, int min, int pos, int max)
{
if ((iterm.CompareTo(Heap[pos]) <= 0 && iterm.CompareTo(Heap[pos + 1]) >= 0) || pos == 0)
{
for (int i = heapSize - 1; i > pos; i--)
{
Heap[i]
= Heap[i - 1];
}
if (pos == 0)
{
Heap[pos]
= iterm;
}
else
{
Heap[pos
+ 1] = iterm;
}
}
else
{
if (iterm.CompareTo(Heap[pos]) > 0)
{
max
= pos;
}
else
{
min
= pos;
}
pos
= Convert.ToInt32((max + min) / 2);
Insert(iterm, min, pos, max);

}
}


}

}

}
posted @ 2011-04-26 09:29  CSDN大笨狼  阅读(531)  评论(0编辑  收藏  举报