活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
1. 概念
索引查找
又称为分块查找
,就是一种介于顺序查找和二分查找之间的一种查找方法。关于索引,是不是就联想到了数据库
中的索引,建立索引之后,就可以大大提高数据库的查询速递。所以索引查找的基本思想是:首先要查找索引表,可以使用二分查找或者顺序查找,然后在确定的块中进行顺序查找。
在实现索引查找中有三个术语:
主表
,是要查找的序列索引项
,一般将主表分为几个块,每个块建立一个索引,这个索引就叫索引项。索引表
,就是索引项的集合。
算法流程:
索引表的结构如下,图片来自《数据结构简明教程》:
(以下解析部分来自博主“一头小山猪”)
- 索引表中的元素分为关键字和地址两部分
- 关键字为从主数据表中提取出来的用于排序的属性,地址为主数据表中对应元素的位置。
- 在索引表中使用折半查找快速定位待查关键字的位置
- 根据关联关系,提取出在主数据表中的对应位置。
算法效率分析:
-
时间复杂度
-
空间复杂度:
O(n)
2. 伪代码
left = 1
right = T.length
position = -1
while left <= right
mid = (left + right) / 2
if T[mid].key == key
position = mid
break
else if T[mid] > key
right = mid - 1
else
left = mid + 1
if position != -1
return T[position].pos
else
return -1
3. 核心代码实现
package iYou.neugle.search;
import java.util.ArrayList;
import java.util.List;
public class Index_search {
class IndexItem {
public int index;
public int start;
public int length;
}
public int m = 100;
public int[] table = new int[] {
101, 102, 103, 104, 105, 201, 202, 203,
204, 301, 302, 303 };
public List<IndexItem> indexTable = new ArrayList<Index_search.IndexItem>();
public static void main(String[] args) {
Index_search index = new Index_search();
// 创建索引
index.CreateIndex();
// 向索引表中插入数据
index.InsertIndex(205);
// 利用索引表查找数据
int result = index.SearchIndex(205);
System.out.println("索引位置为" + result);
}
public void CreateIndex() {
int[] type = new int[10000];
int[] typeNum = new int[10000];
for (int i = 0; i < this.table.length; i++) {
int n = this.table[i] / m - 1;
if (type[n] == 0) {
type[n] = 1;
}
typeNum[n]++;
}
int start = 0;
for (int i = 0; i < typeNum.length; i++) {
if (typeNum[i] == 0) {
break;
}
IndexItem item = new IndexItem();
item.index = i;
item.start = start;
item.length = typeNum[i];
indexTable.add(item);
start += typeNum[i];
}
}
public void InsertIndex(int key) {
int n = key / m - 1;
int index = -1;
// 更新索引表
for (int i = 0; i < this.indexTable.size(); i++) {
if (n == this.indexTable.get(i).index) {
index = this.indexTable.get(i).start
+ this.indexTable.get(i).length;
this.indexTable.get(i).length++;
break;
}
}
for (int i = n + 1; i < this.indexTable.size(); i++) {
this.indexTable.get(i).start++;
}
// 更新数组
int[] temp = new int[this.table.length + 1];
for (int i = 0; i < temp.length; i++) {
if (i < index) {
temp[i] = this.table[i];
} else if (i == index) {
temp[i] = key;
} else {
temp[i] = this.table[i - 1];
}
}
this.table = temp;
}
public int SearchIndex(int key) {
int n = key / m - 1;
int start = -1;
int length = -1;
// 找到索引位置
for (int i = 0; i < this.indexTable.size(); i++) {
if (n == this.indexTable.get(i).index) {
start = this.indexTable.get(i).start;
length = this.indexTable.get(i).length;
break;
}
}
if (start == -1) {
return -1;
}
// 从索引位置找数据
for (int i = start; i < start + length; i++) {
if (this.table[i] == key) {
return i;
}
}
return -1;
}
}