日期:2014-05-20  浏览次数:20665 次

一道面试题, 求更优答案!
有一个Book类型
class Book{
    int bookId;
    //其他成员变量
    Date publishTime;
}

现在一个List中放了很多Book类型的对象,求让List中Book对象按publishTime排序的最快的方法。

我当时写的答案是:让Book类型实现Comparable接口,在compareTo()方法中设置按publishTime比较。然后用Collections.sort()来让其排序。

求更好的答案!
------解决方案--------------------
好吧,你的答案已经比较简单了

当然你也可以这样做:

在往list中添加book类型的时候, 就计算出相应的publishTime的位置,然后使用add(int index, Object obj) 添加

如此,这个list本身就是排过序的了, 只不过需要将此逻辑封装下
------解决方案--------------------
正常的最快的排序算法应该就是快速排序了,也就是你说的让Collection排序。

其实还可以选择空间换时间的办法来排序。
因为毕竟Date的范围并不大,比如1900/1/1到2012/12/12也就112*366个不同数据。
可以申请长度为112*366的数组,然后1900-1-1就放入数组0位置,其他的根据Data很容易算出下标,然后根据下标依次存放。
最后0-112*366遍历这个数组就得到排好序的数据了。
这让复杂度n就解决问题了。

------解决方案--------------------
如果追求简洁,楼主和楼上的办法都是可行的。

如果面试官考的是“层级排序”,有以下两种办法:
不管怎么说,Collections.sort()最好是不要用(新浪微博的内部人员曾经透露过:凡是上来就用Java集合API的一律不通过)。下面是两种思路都是拆分的思想,不知道合不合理:
1、依次把年、月、日作为最高位关键字、次关键字、最低位关键字,利用基数排序(一般利用最低位优先(Least Significant Digit first)法,简称LSD法),进行排序,缺点是辅助空间比较大;这种算法需要你对链表的操作非常熟悉。
2、建立一颗“广义排序树”,最外层的节点的关键字是“年”,每个“年节点”中又包含一个由“月节点”组成的二叉排序树,而每个“月节点”又包含一个由“日节点”组成的二叉排序树;遍历你的集合,依次插入到这个“广义排序树”上,然后嵌套三层“中序遍历递归算法”,即可完成排序。
ps:如果楼主想要体验更加深入的层级排序,可以按照以下需求“自找麻烦”:
把每个学生的成绩按照:语文、数学、英语、物理、化学的任意一种关键字的排列顺序(一共5!=120)进行多级排序(禁止任何集合API,也禁止sql语句的orderby)。步骤:
一、先设计算法,求出这120种全排列(不允许用五重for循环嵌套,请参考百度百科http://baike.baidu.com/view/1710135.htm);
二、设计一种扩展性强大的“五重层级排序函数”(这个估计会有难度,反正我不知道怎么设计),这个函数能被Java反射所利用。
二、再利用反射机制,不同的排列传入的“方法的排列组合”也尽不相同,从而实现所有的排序。
我只是有这个设想而已,但估计很多大牛们早就实现过了。