Java中的优先队列

来源:互联网 发布:数据交易吧 编辑:程序博客网 时间:2024/06/07 02:40

Form一个问题

假设百度搜索引擎一天会搜索M亿条URL,如何根据URL被搜索的次数来找出次数最高的N个URL呢?
个人有一个抽象的思路:
- 先对所有的URL日志文档进行整合,同一类型的当作一个结点,利用B或者B+树搜索的优秀性能来处理
- 再使用优先队列或者是最大值堆来进行一个排序

正确与否先撇开不谈,整合同类URL的过程中会给后续排序减少大量的工作量(但究竟对于这种亿级的数据量还是只有一个朦胧的概念)。不管怎么说,先来研究一下Java中的优先队列好了

优先队列和遍历层次树

优先队列(PriorityQueue)是不同于普通队列的先进先出的队列,每次从队列中取出的是具有最高优先权的元素。这是从Java1.5开始引入的数据结构的接口。

// TestPriorityQueue.javaimport java.util.Comparator;import java.util.PriorityQueue;import java.util.Queue;import java.util.Random;class Student{    int id;    String name;    public Student(){        this.id = 0;        this.name = "";    }    public Student(int id, String name) {        super();        this.id = id;        this.name = name;    }    public int getId() {        return id;    }    public String getName() {        return name;    }}public class TestPriorityQueue {    private static Comparator<Student> stCompare = new Comparator<Student>(){        // 重写了比较器中的compare方法,否则直接把Student类型的元素加入优先队列会报错        @Override        public int compare(Student st1,Student st2){            // 针对Student的id属性进行比较            return (int)(st1.getId()-st2.getId());        }    };    public static void main(String[] args){        Queue<Integer> number = new PriorityQueue<Integer>();// 存放int类型的数据        Random rand = new Random();        for(int i=0;i<5;i++){            //因为实例化时使用了默认的比较器,所以队列新增的元素时都会自动排序            number.add(rand.nextInt(100));        }        for(Integer i : number){            System.out.println(i);        }        System.out.println();        // ----- 下面开始排序自定义类        // 把重写后的比较器作为参数传入优先队列        Queue<Student> students = new PriorityQueue<Student>(5,stCompare);        for(int i=0;i<5;i++){            students.add(new Student(rand.nextInt(10),String.valueOf(i)));        }        // 预计的输出结果会是:不管st.name是怎样的顺序,但是st.id一定是由小到大        for(Student st : students){            System.out.println(st.id + " " + st.name);        }    }}

遍历层次树

怎么百度的都是概念层次树(黑人问号….),相关的知识有如何层次遍历二叉树,思路是
- 使其根节点入队列,然后出队进行访问
- 若左子节点不为空,使左子节点入队
- 若该节点的右子节点,再使右子节点入队
- 重复上面三个步骤,直到访问了所有节点

大概的思路是这样,开的坑已经够多了,这个就先放后面好了 /:doge

又回到了HashMap高性能读写方法?

其实是自己没有绕出这个圈,那天和dalao讨论的时候,ta认为没有什么优化的方法,毕竟HashMap已经被写好放在jar中了,若是使用,怎么会优化呢?

of cause,自己撸一个HashMap实现,这就引出了一个重点,在我们讨论这个问题的时候,前提是什么?,有说可以自己撸吗?不知道,有说必须要用jdk中的HashMap吗?不知道。

So,…….

日常总结

今天被教育“凡是遇到问题的时候,第一个想到的就应该是前提条件”,没有前提条件,问题是不受约束的。看似是一个谁都懂的道理,但真的很多时候,会被自己潜意识认为的条件局限了自己的思维。就这样。

0 0