日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java最小堆解决TopK问题

發布時間:2023/12/3 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java最小堆解决TopK问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自??Java最小堆解決TopK問題

TopK問題是指從大量數據(源數據)中獲取最大(或最小)的K個數據。

TopK問題是個很常見的問題:例如學校要從全校學生中找到成績最高的500名學生,再例如某搜索引擎要統計每天的100條搜索次數最多的關鍵詞。

對于這個問題,解決方法有很多:

方法一:對源數據中所有數據進行排序,取出前K個數據,就是TopK。

但是當數據量很大時,只需要k個最大的數,整體排序很耗時,效率不高。
?

方法二:維護一個K長度的數組a[],先讀取源數據中的前K個放入數組,對該數組進行升序排序,再依次讀取源數據第K個以后的數據,和數組中最小的元素(a[0])比較,如果小于a[0]直接pass,大于的話,就丟棄最小的元素a[0],利用二分法找到其位置,然后該位置前的數組元素整體向前移位,直到源數據讀取結束。

這比方法一效率會有很大的提高,但是當K的值較大的時候,長度為K的數據整體移位,也是非常耗時的。

對于這種問題,效率比較高的解決方法是使用最小堆

最小堆(小根堆)是一種數據結構,它首先是一顆完全二叉樹,并且,它所有父節點的值小于或等于兩個子節點的值

最小堆的存儲結構(物理結構)實際上是一個數組。如下圖:

堆有幾個重要操作:

BuildHeap:將普通數組轉換成堆,轉換完成后,數組就符合堆的特性:所有父節點的值小于或等于兩個子節點的值。

Heapify(int i):當元素i的左右子樹都是小根堆時,通過Heapify讓i元素下降到適當的位置,以符合堆的性質。

回到上面的取TopK問題上,用最小堆的解決方法就是:先去源數據中的K個元素放到一個長度為K的數組中去,再把數組轉換成最小堆。再依次取源數據中的K個之后的數據和堆的根節點(數組的第一個元素)比較,根據最小堆的性質,根節點一定是堆中最小的元素,如果小于它,則直接pass,大于的話,就替換掉跟元素,并對根元素進行Heapify,直到源數據遍歷結束。

最小堆的實現:

public class MinHeap { // 堆的存儲結構 - 數組 private int[] data; // 將一個數組傳入構造方法,并轉換成一個小根堆 public MinHeap(int[] data) { this.data = data; buildHeap(); } // 將數組轉換成最小堆 private void buildHeap() { // 完全二叉樹只有數組下標小于或等于 (data.length) / 2 - 1 的元素有孩子結點,遍歷這些結點。 // *比如上面的圖中,數組有10個元素, (data.length) / 2 - 1的值為4,a[4]有孩子結點,但a[5]沒有* for (int i = (data.length) / 2 - 1; i >= 0; i--) { // 對有孩子結點的元素heapify heapify(i); } } private void heapify(int i) { // 獲取左右結點的數組下標 int l = left(i); int r = right(i); // 這是一個臨時變量,表示 跟結點、左結點、右結點中最小的值的結點的下標 int smallest = i; // 存在左結點,且左結點的值小于根結點的值 if (l < data.length && data[l] < data[i]) smallest = l; // 存在右結點,且右結點的值小于以上比較的較小值 if (r < data.length && data[r] < data[smallest]) smallest = r; // 左右結點的值都大于根節點,直接return,不做任何操作 if (i == smallest) return; // 交換根節點和左右結點中最小的那個值,把根節點的值替換下去 swap(i, smallest); // 由于替換后左右子樹會被影響,所以要對受影響的子樹再進行heapify heapify(smallest); } // 獲取右結點的數組下標 private int right(int i) { return (i + 1) << 1; } // 獲取左結點的數組下標 private int left(int i) { return ((i + 1) << 1) - 1; } // 交換元素位置 private void swap(int i, int j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } // 獲取對中的最小的元素,根元素 public int getRoot() { return data[0]; } // 替換根元素,并重新heapify public void setRoot(int root) { data[0] = root; heapify(0); } }

利用最小堆獲取TopK:

public class TopK { public static void main(String[] args) { // 源數據 int[] data = {56,275,12,6,45,478,41,1236,456,12,546,45}; // 獲取Top5 int[] top5 = topK(data, 5); for(int i=0;i<5;i++) { System.out.println(top5[i]); } } // 從data數組中獲取最大的k個數 private static int[] topK(int[] data,int k) { // 先取K個元素放入一個數組topk中 int[] topk = new int[k]; for(int i = 0;i< k;i++) { topk[i] = data[i]; } // 轉換成最小堆 MinHeap heap = new MinHeap(topk); // 從k開始,遍歷data for(int i= k;i<data.length;i++) { int root = heap.getRoot(); // 當數據大于堆中最小的數(根節點)時,替換堆中的根節點,再轉換成堆 if(data[i] > root) { heap.setRoot(data[i]); } } return topk; } }

?

?

?

總結

以上是生活随笔為你收集整理的Java最小堆解决TopK问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 北条麻妃av在线 | 午夜视频在线播放 | 91在线超碰| 老熟妻内射精品一区 | 性高潮久久久久久久 | 国产一级高清视频 | 精品无码久久久久久久 | 91麻豆精品秘密入口 | 成人免费毛片片v | 国产盗摄精品 | 76少妇精品导航 | 一级黄色免费大片 | 天堂a√在线 | 亚欧日韩av| 国产伦理片在线观看 | 国产69精品一区二区 | www久久久久 | 国产精品国产三级国产 | 天堂av中文在线观看 | 无码人妻丰满熟妇奶水区码 | 人人爽人人草 | 玩弄少妇人妻 | 亚洲Av无码成人精品区伊人 | 成人啪啪网站 | 国产制服在线 | 狐狸视频污 | 贝利弗山的秘密1985版免费观看 | 插插网站| 欧美极品在线播放 | 黄色a一级 | 高清成人免费视频 | 日韩欧美激情在线 | 秋霞视频在线观看 | 亚洲精品一区二区三区精华液 | 97公开视频| 久久久免费在线观看 | 欧美高清视频一区二区三区 | 肉体粗喘娇吟国产91 | 欧美日韩在线免费 | 精品欧美一区二区三区在线观看 | 国产精品少妇 | 国产精品综合 | 亚洲免费观看视频 | 国产无码精品在线播放 | 亚洲在线视频免费观看 | 51福利视频 | 色老头在线视频 | 激情黄色小视频 | 99精品偷自拍 | 在线观看免费看片 | 99riav国产在线观看 | 国产一区二区三区视频网站 | 校园激情亚洲 | 日韩av中文在线 | 国产乱码精品一区二区 | 香蕉久久久久久久av网站 | 影音先锋久久久久av综合网成人 | 日韩一区在线播放 | 拍摄av现场失控高潮数次 | xxxwww18 | 午夜久久久久 | 成人www视频 | 久草视频在线看 | 成人精品视频在线观看 | 日本免费中文字幕 | 久久婷婷一区二区 | 亚欧在线观看 | 亚洲激情av | av中文字幕网站 | 女女同性女同一区二区三区九色 | 成人精品自拍 | 天天躁日日躁aaaaxxxx | 欧美女人一区二区 | 欧美a级大片 | 白丝美女被草 | 国产人成一区二区三区影院 | 91黄视频在线观看 | 国产一区二区三区四区五区在线 | 亚州欧美在线 | 精品成人免费一区二区在线播放 | 亚洲综合视频在线播放 | 精品亚洲一区二区三区四区五区高 | 手机av在线播放 | 亚洲中文字幕一区二区在线观看 | 99青青草 | 天堂视频免费看 | 亚洲美女性视频 | 国产男男gay网站 | 欧美一级啪啪 | 无码人妻丰满熟妇区五十路 | 美女xx00 | 毛片视频免费观看 | 性喷潮久久久久久久久 | 色一情一乱一伦一区二区三区 | 久久精品5 | 久久久久久久久久久99 | 成人在线综合 | 二区三区在线视频 | 亚洲人 女学生 打屁股 得到 |