• 最大堆 最小堆 解决TOPK问题


    堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点;最小堆的父节点值均小于子节点;

    一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值:

    节点i的父节点为(i-1)/2;

    节点j的左子结点:j * 2 + 1;

    节点j的右子结点:j * 2 + 2;

    以下代码实现了最大堆最小堆,当比较函数使用std::greater,得到最大堆,当比较函数使用std::less得到最小堆;

    代码及测试用例如下:

      1 //最大最小堆
      2 //MaxMinHeap.h
      3 
      4 #pragma once
      5 #include <assert.h>
      6 
      7 using namespace std;
      8 
      9 template <typename T>
     10 void mswap(T &a, T &b)
     11 {
     12     T tmp = a;
     13     a = b;
     14     b = tmp;
     15 }
     16 
     17 template <typename T,typename Compare = std::less<T>>
     18 class MaxMinHeap
     19 {
     20 public:
     21     int hSize ;    //堆空间
     22     int hCurNum;//堆内已占用空间
     23     T *data;
     24 
     25 private:
     26     Compare comp;//比较函数
     27 public:
     28     MaxMinHeap(int size)
     29     {
     30         hSize = size;
     31         assert(hSize>0);
     32         data = new T[hSize];
     33         hCurNum = 0;
     34     };
     35     ~MaxMinHeap(void)
     36     {
     37         if(data!=NULL)
     38             delete []data;
     39     };
     40 
     41     void headAdd(T num)
     42     {
     43         if (hCurNum==hSize)
     44         {
     45             if (comp(num,data[0]))//greater 大顶堆 保留最小的K个数;less 小顶堆 保留最大的K个数
     46                 return;
     47             data[0]=num;
     48             HeapFixDown(0,hCurNum);
     49         }
     50         else
     51         {
     52             data[hCurNum++]=num;
     53             HeapFixUp(hCurNum-1);
     54         }
     55     };
     56     //最大堆排序后得到升序序列;最小堆排序后得到降序序列
     57     void sort()
     58     {
     59         for (int i=hCurNum-1; i >=1 ; --i)
     60         {
     61             mswap(data[i],data[0]);
     62             HeapFixDown(0,i);
     63         }
     64     }
     65 
     66     void GetHnum(T &n)//获取最大堆的最小值或者最小堆的最大值
     67     {
     68         n = data[0];
     69     };
     70     void HeapFixUp(int index)
     71     {
     72         assert (index < hCurNum);
     73         T tmp=data[index];
     74         int j = (index - 1)/2;//父节点
     75         while(j>=0 && index !=0)
     76         {
     77             if(comp(data[j],tmp))
     78                 break;
     79             data[index]=data[j];
     80             index = j;
     81             j = (index - 1)/2;
     82         }
     83         data[index]=tmp;
     84     };
     85 
     86     //从节点index开始进行向下调整
     87     void HeapFixDown(int index, int n)
     88     {
     89         assert(index<hCurNum);
     90         assert(n<hCurNum);
     91 
     92         T tmp=data[index];
     93         int j = index*2+1;
     94         while(j<n)
     95         {
     96             if(j+1 < n && comp(data[j+1],data[j]))//大顶堆中左右孩子找最大的,小顶堆左右孩子找最小的
     97                 ++j;
     98             if(comp(tmp,data[j]))
     99                 break;
    100             data[index]=data[j];
    101             index = j;
    102             j = index*2+1;
    103         }
    104         data[index]=tmp;
    105     };
    106 };
    107 
    108 #include <functional>
    109 #include <iostream>
    110 #include "MaxMinHeap.h "
    111 
    112 using namespace std;
    113 
    114 int main(int argc ,  char ** argv)
    115 {
    116     MaxMinHeap<float,greater<float>> test(20);
    117 
    118     for (int i = 0 ;i < 20; ++i)
    119     {
    120         test.headAdd(-i*2+38);
    121     }
    122     for (int i = 0 ; i < 20 ; ++i)
    123     {
    124         cout<<test.data[i]<<endl;
    125     }
    126     test.sort();
    127     for (int i = 0 ; i < 20 ; ++i)
    128     {
    129         cout<<test.data[i]<<" ";
    130     }
    131     cout<<endl;
    132     return 0;
    133 }
  • 相关阅读:
    10.浮动样式
    09.圆角样式及渐变色样式
    08.背景样式
    Oracle中dual表的用途介绍
    PL/SQL包
    Oracle表数据和表结构对比
    oracle如何判断某张表是否存在
    awk编程基础
    Oracle左连接、右连接、全外连接以及(+)号用法
    SpringMVC的三种处理器适配器
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/4323927.html
Copyright © 2020-2023  润新知