查找算法-稠密索引、分块索引、倒排索引

来源:互联网 发布:淘宝客服话术范文 编辑:程序博客网 时间:2024/05/16 08:02

1.稠密索引

稠密索引时指在线性索引中,将数据集中的每个记录都对应一个索引项 。对于索引项一定是按照关键码有序的排列 索引项有序意味着可以使用顺序查找算法,这是稠密索引的有点, 但是如果数据集非常大,意味着索引也得有同样的数据集长度规模。


public class Index {    public int key;    public Object value;    public int size;//分块存储数量    @Override    public String toString() {        return "Index{" +                "key=" + key +                ", value=" + value +                ", size=" + size +                '}';    }}

public class Student implements Comparable {    public Student(int no, String name) {        this.no = no;        this.name = name;    }    public int no;    public String name;    @Override    public String toString() {        return "Student{" +                "no=" + no +                ", name='" + name + '\'' +                '}';    }    @Override    public int compareTo(Object o) {        Student other = (Student) o;        if (no < other.no) //这里比较的是什么 sort方法实现的就是按照此比较的东西从小到大排列            return -1;        if (no > other.no)            return 1;        return 0;    }}

 public static int binarySearch(Index[] array, int key) {        if (array.length > 0) {            int low, high, mid;            low = 0;            high = array.length - 1;            while (low <= high) {                mid = (low + high) / 2;//折半                if (key < array[mid].key)                    high = mid - 1;                else if (key > array[mid].key)                    low = mid + 1;                else                    return mid;            }        }        return -1;    }    public static Student denseIndex(Student[] array, int key) {        if (array != null && array.length > 0) {            Arrays.sort(array);            Index[] list = new Index[array.length];            //建立索引            for (int i = 0; i < array.length; i++) {                Index index = new Index();                index.key = array[i].no;                index.value = array[i];                list[i] = index;            }            //根据索引关键码搜索            int code = binarySearch(list, key);            if (code != -1) {                return (Student) list[code].value;            }        }        return null;    }

2.分块索引

分块有序-是吧数据集合的记录分成了若干份,并且这些块需要满足2个条件
     1)块内无序,即每一块内的记录不要求有序。(有序更好,但需要付出大量时间和空间代价)
     2)块间有序-例如要求第二块所有记录的关键字均要大于第一块所有记录的关键字,第三块的所有记录要大于第二块的所有记录关键字,因为只有块间有序,才能提高查找效率
      分块索引的平均查找长度ASL=根号n+1  高于o(n)小于折半查找o(logn)


  public static int blockSearch(Index[] array, int key) {        if (array.length > 0) {            int result, low, high, mid;            result = 0;            low = 0;            high = array.length - 1;            while (low <= high) {                mid = (low + high) / 2;//折半                if (key < array[mid].key) {                    high = mid - 1;                    result = high;                } else if (key > array[mid].key) {                    low = mid + 1;                    result = mid;                } else                    return mid;            }            return result;        }        return -1;    }

 public static Student blockIndex(Student[] array, int block, int key) {        if (array != null && array.length > 0) {            if (block < 1 || block > array.length) {                return null;            }            Arrays.sort(array);//为了方便构造 块内有序 其实可以无序            Index[] list = new Index[block];            int blocksize = array.length / block;            //建立索引及数据分块            for (int i = 0; i < array.length; i++) {                if (i % blocksize == 0 || block == 1) {//分块建立索引                    Index index = new Index();                    index.key = array[i].no;                    index.value = array[i];                    if (block == 1) {//只分一块 首个是索引                        index.size = array.length;                        list[0] = index;                        break;                    } else if (i / blocksize == block - 1) {//长度和分块个数不均匀,剩下最后的数据放在最后一块                        index.size = array.length - i;                        list[block - 1] = index;                        break;                    } else if (i / blocksize < block - 1) {                        index.size = blocksize;                        list[i / blocksize] = index;                    }                }            }            //根据索引关键码搜索对应的块            int mid = blockSearch(list, key);            System.out.println("mid:" + mid);            if (mid != -1) {                Index index = list[mid];//找出索引                System.out.println("index:" + index);                for (int i = 0; i < index.size; i++) {//块内无序 顺序查找                    System.out.println("array[i]:" + array[(mid * blocksize) + i]);                    if (key == array[(mid * blocksize) + i].no) {                        return array[(mid * blocksize) + i];                    }                }            }        }        return null;    }

3.倒排索引

倒排索引的概念很简单:就是将文件中的单词作为关键字,然后建立单词与文件的映射关系。 当然,你还可以添加文件中单词出现的频数等信息。 倒排索引是搜索引擎中一个很基本的概念,几乎所有的搜索引擎都会使用到倒排索引。

索引项的通用结构是:

     1)次关键码,例如上面的英文单词
     2) 记录号表,例如上面的文章编号

 其中记录号表存储具有相同次关键字的所有记录的记录号(可以是指向记录的指针或者是该记录的主关键字)
     

 public static List<String> invertedIndex(String[] array, String word) {        HashMap<String, List<String>> lists = new HashMap<>();        if (array != null && array.length > 0) {            //建立索引            for (int i = 0; i < array.length; i++) {                String page = array[i];                String[] words = page.split(" ");                for (String str : words) {                    if (lists.containsKey(str)) {                        List<String> pages = lists.get(str);                        pages.add(array[i]);                    } else {                        List<String> pages = new ArrayList<>();                        pages.add(array[i]);                        lists.put(str, pages);                    }                }            }            return lists.get(word);        }        return null;    }

2 0
原创粉丝点击