数据结构与算法--从一百万个数字中得到前10大的数

 1. 算法如下:根据快速排序划分的思想 
(1) 递归对所有数据分成[a,b)b(b,d]两个区间,(b,d]区间内的数都是大于[a,b)区间内的数 
(2) 对(b,d]重复(1)操作,直到最右边的区间个数小于100个。注意[a,b)区间不用划分 
(3) 返回上一个区间,并返回此区间的数字数目。接着方法仍然是对上一区间的左边进行划分,分为[a2,b2)b2(b2,d2]两个区间,取(b2,d2]区间。如果个数不够,继续(3)操作,如果个数超过100的就重复1操作,直到最后右边只有100个数为止。 


2.先取出前100个数,维护一个100个数的最小堆,遍历一遍剩余的元素,在此过程中维护堆就可以了。具体步骤如下: 
step1:取前m个元素(例如m=100),建立一个小顶堆。保持一个小顶堆得性质的步骤,运行时间为O(lgm);建立一个小顶堆运行时间为m*O(lgm)=O(m lgm);       
step2:顺序读取后续元素,直到结束。每次读取一个元素,如果该元素比堆顶元素小,直接丢弃 
如果大于堆顶元素,则用该元素替换堆顶元素,然后保持最小堆性质。最坏情况是每次都需要替换掉堆顶的最小元素,因此需要维护堆的代价为(N-m)*O(lgm); 
最后这个堆中的元素就是前最大的10W个。时间复杂度为O(N lgm)。 


3.分块查找 

先把100w个数分成100份,每份1w个数。先分别找出每1w个数里面的最大的数,然后比较。找出100个最大的数中的最大的数和最小的数,取最大数的这组的第二大的数,与最小的数比较。。。。


  1. package BigData;  
  2.   
  3. import java.io.*;  
  4. import java.util.PriorityQueue;  
  5. import java.util.Queue;  
  6.   
  7. public class FileTest {  
  8.     public FileTest() {  
  9.     }  
  10.   
  11.     public static void main(String[] args) {  
  12.         // madeData();  
  13.         sortData();  
  14.     }  
  15.   
  16.     private static void sortData() {  
  17.         FileReader fr = null;  
  18.         BufferedReader br = null;  
  19.         Queue<Integer> priorityQueue = new PriorityQueue<Integer>(100);  
  20.         try {  
  21.             fr = new FileReader("F:/add3.txt");  
  22.             br = new BufferedReader(fr);  
  23.             int temp;  
  24.             int temp1;  
  25.             String str = null;  
  26.             long begin3 = System.currentTimeMillis();  
  27.             while ((str = br.readLine()) != null) {  
  28.                 temp = Integer.valueOf(str);  
  29.                 if (priorityQueue.size() < 100) {  
  30.                     priorityQueue.add(temp);  
  31.                 } else {  
  32.                     temp1 = priorityQueue.poll();  
  33.                     if (temp1 < temp) {                        
  34.                         priorityQueue.offer(temp);  
  35.                     }else{  
  36.                         priorityQueue.offer(temp1);  
  37.                     }  
  38.                 }  
  39.                 System.out.println("FileReader执行耗时:" + priorityQueue.toString());  
  40.             }  
  41.             br.close();  
  42.             fr.close();  
  43.             long end3 = System.currentTimeMillis();  
  44.             System.out.println("FileReader执行耗时:" + (end3 - begin3) + " 豪秒");  
  45.             System.out.println("FileReader执行耗时:" + priorityQueue.toString());  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         } finally {  
  49.         }  
  50.     }  
  51.   
  52.     private static void madeData() {  
  53.         FileWriter fw = null;  
  54.         int count = 1000000;// 写文件行数  
  55.         try {  
  56.             fw = new FileWriter("F:/add3.txt");  
  57.             int temp = (int) (Math.random() * 1000000);  
  58.             long begin3 = System.currentTimeMillis();  
  59.             for (int i = 0; i < count; i++) {  
  60.                 temp = (int) (Math.random() * 1000000);  
  61.                 fw.write(temp + "\r\n");  
  62.             }  
  63.             fw.close();  
  64.             long end3 = System.currentTimeMillis();  
  65.             System.out.println("FileWriter执行耗时:" + (end3 - begin3) + " 豪秒");  
  66.         } catch (Exception e) {  
  67.             e.printStackTrace();  
  68.         } finally {  
  69.         }  
  70.     }  
  71. }  
维护一个堆,然后向里面添加数据。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值