堆面试题总结

【堆面试题】
1. 实现堆创建,插入及删除
2. 优先级队列
3. 100w个数中找到最大的前K个数
4. 堆排序
【堆面试题解答】
1. 实现堆创建,插入及删除
在实现堆的创建时,我们以大堆为例,大堆的创建需要自上向下调整堆,创建堆的时间复杂度为O(log2 n)。

 void AdjustDown(vector<int>& arr,int parent,int size)
  {
    int child=parent*2+1;
    if(child+1<size&&arr[child]<arr[child+1])
        child=child+1;
     while(child<size)
    {
        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);
  }

  1. 优先级队列的底层搭建
    优先级队列的底层为堆,是一种特殊的队列,这种队列会自动的把队列里的数排序(默认从大到小,使用“<”判断),而且还可以把数按照特定的方法排列!(包括结构体和重载”<”)。
//优先级队列的声明方式
//int为默认方式
priority_queue <int> i;
priority_queue <double> d;
//最常用的声明方式
priority_queue <node> q;
//node是一个结构体
//结构体里重载了‘<’小于符号
priority_queue <int,vector<int>,greater<int> > q;
//不需要#include<vector>头文件
//注意后面两个“>”不要写在一起,“>>”是右移运算符
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的末尾元素
  1. 100w个数中找到最大的前K个数
    思想:从100w个数中取出K个元素构建小堆,再从原数据中取出数据和堆顶元素比较。若小,不管;若大,替换堆顶元素,如果不满足小堆,则调整堆,直到N-K个元素全部比较完成。
#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;
           }
      }
}
  1. 堆排序
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;
      if(child+1<arr.size()&&Greater()(arr[child+1],arr[child]))
         child=child+1;
      while(child<arr.size())
     {
          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--;
     }

 }          

猜你喜欢

转载自blog.csdn.net/qq_37954088/article/details/81545921