zoukankan      html  css  js  c++  java
  • topK问题解法

    topK问题的最佳解法是堆排,下面介绍用堆排来解决该问题。

    堆排解决topK问题的思路,取出前K个数,最重要的就是要减少比较的次数,用堆排维护一个K大小的堆,比如一个小顶堆,则堆顶为堆中最小的值,将堆外的元素依次与堆顶比较,若大于堆顶,则与堆顶交换,并将堆重新调整为小顶堆,依次比较完所有元素。则堆顶为堆中的最小元素,且为所有元素中的第K大的元素,则整个堆则为前K大的K个元素。若要取前K个小的数,则要使用大顶堆。
     
    测试代码如下:
    var array = [10,7,8,6,3,1,5,2,4,9];
    var k =6;
    var len = array.length;
    
    fHeapSortK(array,len,k);
    
    console.log('topK result: ' + array);
    
    //堆排取出top K数据,小顶堆取最大的前K个数据,大顶堆取最小的前K个数据
    function fHeapSortK(data,length,k){
        fBuildSmallHeap(data,k);
        //将前k个后面的数字,依次与堆顶比较,大于堆顶,就与堆顶交换
        for(var i=k;i<length;i++){
            if(data[i] > data[0]){
                //交换堆顶与较大值
                swap(data,0,i);
                //0至k-1,前面K个数字调整为小顶堆
                fAdjustSmallHeap(data,0,k-1);
            }
        }
    }
    //构造小顶堆
    function fBuildSmallHeap(data,length){
        //length是堆的大小,前K个数字,则是需要一个K长度的堆
        //将数组中的前 m = Math.floor(length/2) 作为父节点,后面 length - m 个节点,都是父节点的孩子节点
        //依次将所有父节点为三角形的堆,都调整为小顶堆,这样整个length长度的堆,就调整为一个小顶堆
        //调整过程是递归的过程,实际发生的调整次数,不只 m 次
        for(var i = Math.floor(length/2);i--;){
            fAdjustSmallHeap(data,i,length);
        }
        console.log('small heap ' + data)
    }
    //调整堆为小顶堆
    function fAdjustSmallHeap(data,loc,length){
        var lChild = 2 * loc + 1,
            rChild = 2 * loc + 2,
            smallest = loc;
        //判断左孩子,是否小于,小于就交换
        if(lChild <= length && data[lChild] < data[smallest]){
            smallest = lChild;
        }
        //判断有孩子,是否小于,小于就交换
        if(rChild <= length && data[rChild] < data[smallest]){
            smallest = rChild;
        }
        //最小索引不是原父节点的索引,则需要交换父节点和孩子
        if(smallest != loc){
            //交换父节点与左右孩子中最小的节点
            swap(data,loc,smallest);
            //交换后,父节点为孩子的三角形,要继续调整为小顶堆,爷爷节点为孩子的也要调整,递归进行
            fAdjustSmallHeap(data,smallest,length);
        }
    }
    //交换数据
    function swap(data,a,b){
        var temp = data[a];
        data[a] = data[b];
        data[b] = temp;
    }
  • 相关阅读:
    也谈谈关于WEB的感想
    spring boot,https,双向ssl认证
    Spring Cloud Gateway(二)
    Spring Cloud Gateway(一)
    .Net Web Service 自定义返回值命名
    随便记一下,C#并行环境操作Winform的代码段
    随便记一下,解决Windows Server 2012无法远程登录的方法
    记录C#控件DataGridView绑定BindingList无法排序问题(转)
    记录SQL Server 2019链接Oracle 11g R2的过程
    Json CPP 中文支持与入门示例
  • 原文地址:https://www.cnblogs.com/mengff/p/7768085.html
Copyright © 2011-2022 走看看