0

我正在使用 Java 开发一个简单的搜索引擎。

搜索引擎首先将包含要搜索的文件(txt 文件)的目录名称作为输入,并且在每个文件中包含许多单词。

然后搜索引擎为目录中遇到的所有单词创建一个倒排索引。引擎读取每个文件并将每个单词插入到 doubleLinkedList 中。

问题是,当我处理包含 100 个 .txt 文件的目录时:

索引时间:~201ms 排序时间:2463ms


排序一个目录包含 1000 个文件

索引时间:2461ms 排序时间:922654ms


排序一个目录包含 10000 个文件

大约 10 小时 :(


  1. 有什么方法可以减少执行时间?

  2. 我使用了插入排序,所以对排序算法有什么建议吗?

DoubleLinkedList 类的实现

public class DoubleLinkedList<T> {
    private Node<T> head;
    private Node<T> current;

    public DoubleLinkedList(){
        head = current = null;
    }
    public boolean empty(){
        return head == null;
    }
    public boolean last(){
        return current.next==null;
    }
    public boolean first(){
        return current.previous == null;
    }
    public boolean full(){
        return false;
    }
    public void findFirst(){
        current = head;
    }
    public void findNext(){
        current = current.next;
    }
    public void findPrevious(){
        current = current.previous;
    }
    public T retrieve(){
        return current.data;
    }
    public void update(T val){
        current.data = val;
    }
    public void insert(T val){
        if(head == null){
            head = current = new Node<T>(val);
        }else{
            Node<T> tmp = new Node<T>(val);
            tmp.next = current.next;
            tmp.previous = current;
            if(current.next != null)
                current.next.previous = tmp;
            current.next = tmp;
            current = tmp;
        }
    }
    public void remove(){
        if(current == head){
            head = head.next;
            if(head!=null){
                head.previous=null;
            }
        }else{
            current.previous.next = current.next;
            if(current.next!=null){
                current.next.previous = current.previous;
            }
        }
        if(current.next == null){
            current = head;
        }else{
            current = current.next;
        }
    }


}
4

3 回答 3

4

插入排序在(最坏情况)O(n^2)时间内运行。

O(nlogn)您可以尝试在 (IIRC)时间内运行的 Mergesort、QuickSort 或 HeapSort 。这会快得多。

于 2012-11-25T16:43:18.763 回答
1

当然还有更快的方法。事实上,有几十种更快的方法:-)

但除非你喜欢重新发明轮子,否则你可以简单地使用Collections.sort(list). 此外,如果性能很重要,我建议使用ArrayList相当 a LinkedList,因为它允许更好的引用位置并占用更少的内存。

对于长度为 10000 的列表,与插入排序相比,这应该将执行时间减少 3 个数量级(即 1000 倍)。

于 2012-11-25T16:46:13.757 回答
0

使用ArrayList, 然后调用list.trim()来删除空的保留列表空间,然后只需调用Collections.sort(list). 比LinkedList差 99.5% ArrayList

如果这仍然很慢:接下来只需尝试:
使用 ArrayList,构建一个String[] words,然后排序Arrays.sort( words)
。Collection.sort 使用(修改后的)MergeSort。

该算法提供有保证的 n log(n) 性能。

通过避免集合的开销,您可以做得更快一点,我曾经使用 MyArrayListInt 和 Quicksort 做到这一点。

于 2012-11-25T17:04:15.340 回答