概括:用数组实现的带头尾指针的双向减序链表,使用插入排序,并通过中位数下标来决定是使用尾部插入还是头部插入的,实现从大量数据(存储于文件)中提取其最大100个的算法。优点,读取文件一遍,空间的非动态申请,无数组插入排序的大量"后移"操作,避免有序文件带来的最差表现。
缘起:这个月初,有同学去腾讯面试,这是最后一题,从1000万个数据中取出最大的100个,觉得点意思。我第一反应和同学是一样的,遍历这个1000万的超级数组或文件100次,每次找出当前最大的那个,并从中移除。第二反应是,显然100*1000万的规模太大,不可取,特别是,当1000万的数据在文件中,(如果是int型数据,32位机,将有40M,实际字段可能不止sizeof(int)),文件读取更耗时,更别说100遍了,最好能只读取一遍,从可以使得算法适用更大规模的存储在文件中的数据。
解决过程:好久不用考虑算法了,突然这么一个问题,头脑有点空,只好点开一本讲算法的电子书,从目录开始,第一章是算法的复杂性度量,然后是数据结构,然后是排序,一些相关的知识犹如从硬盘载入内存。问题的相关知识被串起来。觉得这本身是个排序问题,排序算法一大堆,但基本操作都是比较和赋值(+空间分配)。回顾各种排序算法的特点后,觉得插入排序,即每次插入到合适的位置,比较符合。主要是每次插入后都能得到一个有序的“数组”供后续数组插入,而插入一个元素到一个有序数组,有些特殊的优势,总结来说是减少比较次数:例如对一个减数组,你先比较后面的(较小的数据),