【堆面试题】
1. 实现堆创建,插入及删除
2. 优先级队列
3. 100w个数中找到最大的前K个数
4. 堆排序
【堆面试题解答】
1. 实现堆创建,插入及删除
在实现堆的创建时,我们以大堆为例,大堆的创建需要自上向下调整堆,创建堆的时间复杂度为O(log2 n)。
void AdjustDown(vector<int>& arr,int parent,int size)
{
int child=parent*2+1;
while(childif(child+11])
child=child+1;
if(arr[child]>arr[parent])
{
swap(arr[child],arr[parent]);
parent=child;
child=2*parent+1;
}
else
break;
}
}
void CreateHeap(vector<int> & arr)
{
int size=arr.size();
int parent=(size-1)>>1;
for(;parent>=0;--parent)
{
AdjustDown(arr,parent,size);
}
}
//堆删除堆顶元素的时间复杂度为O(log2 n)
void DeleteHeap(vector<int>& arr)
{
int size=arr.size();
if(size<=0)
return;
swap(arr[0],arr[size-1]);
arr.pop_back();
int parent=(arr.size-2)>>1;
for(;parent>=0;--parent)
{
AdjustDown;
}
}
//堆插入的时间复杂度为O(log2 n)
void AdjustUp(vector<int>& arr,int child)
{
int parent=(child-1)>>1;
while(child>0)
{
if(arr[child]>arr[parent])
{
swap(arr[child],arr[parent]);
child=parent;
parent=(child-1)>>1;
}
else
break;
}
}
void InsertHeap(vector<int>& arr,int data)
{
arr.push_back(data);
int child=arr.size-1;
AdjustUp(arr,child);
}
//优先级队列的声明方式
//int为默认方式
priority_queue <int> i;
priority_queue <double> d;
//最常用的声明方式
priority_queue q;
//node是一个结构体
//结构体里重载了‘<’小于符号
priority_queue <int,vector<int>,greater<int> > q;
//不需要#include头文件
//注意后面两个“>”不要写在一起,“>>”是右移运算符
priority_queue <int,vector<int>,less<int> >q;
//优先级队列的基本操作
q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素
q.back();//返回q的末尾元素
#define M 100000
#define K 100
//向下调整成最小堆
void AdjustDown(int parent, int* a )
{
int child = parent * 2 + 1;
while (child < K )
{
if (child + 1 < K && a[child] > a[child + 1])
{
child++;
}
if (a [child] < a[parent])
{
swap( a[child], a [parent]);
parent = child;
child = parent * 2 + 1;
}
else
break;
}
}
void GetKMaxNum(int array[], int top [])
{
assert(K < M);
//取array数组里面的前K个数给top数组
for (int i = 0; i < K; i++)
{
top[i] = array [i];
}
//建最小堆
for (int i = (K - 2) / 2; i >= 0;i--)
{
AdjustDown(i, top);
}
//取array里面剩下的数和top里面的首元素进行比较,如果比首元素大,则替换,然后再次调整成最小堆
for (int i = K; i < M; i++)
{
if (array [i]>top[0])
{
top[0] = array [i];
AdjustDown(0, top);
}
void Print(int *top)
{
int count = 0;
for (int i = 0; i < K; i++)
{
cout << top[i] << " " ;
count++;
if (count % 6==0 )
{
cout << endl;
}
}
}
Class Greater
{
bool operator()(int left,int right)
{
return left>right;
}
};
class Less
{
bool operator()(int left,int right)
{
return left<right;
}
};
void AdjustDown(vector<int>& arr,int parent)
{
int child=2*parent+1;
while(childif(child+11],arr[child]))
child=child+1;
if(Greater()(arr[child],arr[parent]))
{
swap(arr[child],arr[parent]);
parent=child;
child=parent*2+1;
}
else
break;
}
}
void SortHeap(vector<int>& arr)
{
int size=arr.size();
int parent=(size-2)>>1;
for(;parent>=0;--parent)
{
AdjustDown(arr,parent);
}
int end=size-1;
while(end)
{
swap(arr[0],arr[end]);
AdjustDown(arr,0);
end--;
}
}