您的位置:首页 > 其它

寻找最小的k个数,处理海量数据的思想

2016-07-07 11:24 281 查看
题目:在n个数中找出最小的k个数,例如在1,3,5,7,9,2,4,6,8,10中找出最小的4个数,那么结果就为1,2,3,4

分析:最为直接的办法就是将这n个数先进行排序,然后再取出前k个即为最小的k个数,但这绝对得不到面试官的青睐,因为这样做太笨拙。现在可以将数据插入到小堆中,然后将前堆前面的K个数输出就可以。可以利用这样的思想处理海量数据。

class Heap //建立小堆
{
public:
Heap( int* parr ,int size)
{
for (int i = 0; i < size; i++)
{
_v.push_back( parr[i]);
}

for (int i = _v.size() / 2 - 1; i>0; i--)
{
_AdjustDown(i);
}
}

void Push(const int& d)
{
_v.push_back( d);
_AdjustUp(_v.size()-1);
}

int Top()
{
return *_v.begin();
}
void Pop()
{
swap(_v[0], _v[_v.size() - 1]);
_v.pop_back();
_AdjustDown(0);
}

void _AdjustUp(int child)
{
int parent = child / 2 - 1;
while (parent>0)
{
if (child + 1 < _v.size() && _v[child] > _v[ child + 1])
child++;
if (_v[parent] > _v[child ])
{
swap(_v[parent], _v[child]);
child = parent;
parent = child / 2 - 1;
}
else
break;
}
}
void _AdjustDown(int parent)
{
int child = parent *2+1;
while (child<_v.size())
{
if (child + 1 < _v.size() && _v[child] > _v[child + 1])
child++;
if (_v[parent ]>_v[child])
{
swap(_v[ parent], _v[child]);
parent = child;
child = parent * 2 + 1;
}
else
break;
}
}

private:
vector<int > _v;
};
/**********************************************************/

void test()
{
int arr[10] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
Heap h(arr,10);
int k = 4;
for (int i = 0; i < k; i++)
{
cout << h.Top() << " ";
h.Pop();
}
cout << endl;
}


[align=left]也可以建立k个数的大堆,先将数组中的前k个数字进堆,然后再找出这k个数字中的最大数字max,然后再从数组中第k+1个数字遍历,让这个数字和和max进行比较,如果该数字比max还大就将其跳过,如果小于max就将这两个数字进行交换,将堆进行调整。循环这个动作直到将数组遍历完成。 这样做可以比将size元素直接进堆要节省空间,这个更有利于处理海量数据。[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: