重读数据结构之优先级队列

队列是一种先进先出的结构,但优先级队列需要对后挤进去的数据进行排序,如果足够大的话会排至队首。它可以用来维护一堆数据中最大(最小)的N个数据,在这里用大顶堆(完全二叉树)来实现不停输入整数时找出K个最小的数,通过与堆顶的比较,决定是否顶替堆顶并再次排序。这也是为了给KD树求K近邻做个铺垫~

大顶堆在数组中的表现是数组下标n是下标2n与2n+1的父节点,同时2n的节点大于它的兄弟节点,因此在有数据顶替堆顶之后,再依次与其子节点比较,若有需要则替换。这样每一次维护的平均时间复杂度是nlog(n)。

开心写代码:


#include <iostream>
using namespace std;

int *a;//初始化数组

//交换位置
void swapData(int a[],int i,int j)
{
  int temp;
  temp = a[i];
  a[i] = a[j];
  a[j] = temp;
}

//维护大顶堆
void reorderQueue(int a[],int n)
{
  int q;
  //检查从堆顶沉下来的数据是否需要与子节点交换
  for(int i = 1;i < n/2+1;i++)
  {
    q=2*i;
    if(q+1 > n) break;
    
    if(a[q] < a[q+1]) swapData(a,q,q+1);
    if(a[i] < a[q]) swapData(a,i,q);
  }
}

void insertData(int a[],int insertInt,int n,int K)
{
  if(n <= K)
  {
    a[n]=insertInt;
    reorderQueue(a,n);
  }
  else if(n > K && insertInt < a[1])
  {
    a[1]=insertInt;
    reorderQueue(a,K);
  }
  else
  {
    cout<<"a too big integer"<<endl;
  }
}

int main()
{
  int K;//从数据中找最小的K个数
  cout<<"Please input K"<<endl;
  cin >> K;
  int *a = new int[K+1];
  a[0]=-1;
  cout<<"Please input data"<<endl;
  int n = 1;
  int insertInt;
  while(cin>>insertInt)
  {
    insertData(a,insertInt,n,K);
    ++n;
    for(int i = 1;i < K+1;i++)
    {
      cout<<a[i]<<" ";
    }
    cout<<endl;
  }

  delete a;
  return 0;
}

通过堆排序,可以在消耗较少内存的情况下找到大量数据中最大(小)的若干数据。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值