查找前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);

}
}


}

}

}

你可能感兴趣的:(算法)