基础算法-查找:线性索引查找

前面介绍的几种查找的算法都是基于数据有序的基础上进行的。但是在实际的应用中,很多数据集的可能有竟然的数据量,面对这些海量的数据,要保证记录全部按照当中的某个关键字有序,其时间代价是非常昂贵的,所以这种数据通常都是按先后顺序存储的。

那么如何能够快速的查找到需要的数据呢?办法就是--索引。

索引就是把一个关键字与它对应的记录相关联的过程。一个索引有若干个索引项构成,每个索引项至少应包括关键字和对应的记录在存储器中的位置等信息。

索引按照结构可以分为线性索引、树形索引和多级索引。所谓的线性索引就是将索引项集合组织为线性结构,也称为索引表。

稠密索引

稠密索引是指在线性索引表中,将数据集中的每个记录对应一个索引项。并且索引项一定是按照关键码有序的排列。

索引项有序也就意味着,在查找关键字时,可以用到折半、插值、斐波那契等有序的查找算法。

稠密索引的改进的地方在于:它简化了庞大的原数据集,使原本不能装入内存的庞大的数据集,能一次性的装入内存,并且能够在内存中实现关键字码的排序,并且每一个索引项能够指向磁盘中它代表的原数据记录。

能利用高级的查找算法,这显然是稠密索引的优点,但是如果数据集非常的大,那么索引表也是非常的大,对于内存有限的计算机来说,不得不把索引表也放到磁盘中,这样就大大的降低了效率。

分块索引

稠密索引因为索引项与数据集的记录个数相同,所以空间代价很大。为了减少索引项的个数,对数据集进行分块,使其分块有序,然后在对每一块建立一个索引项,从而减少索引项的个数。

分块有序,就是把数据集的记录分成了若干块,这些块需要满足的条件是:

块内无序,块间有序。

上图中定义的索引项的结构分为三个数据项:

(1)最大关键码,它存储了每一块中的最大关键字,这样的好处是可以使得在它之后的下一块中的最小关键字也能比这一块最大的关键字要大。

(2)存储了块中记录的个数,以便于循环时使用。

(3)用于指向块首数据元素的指针,便于开始对这一块中记录遍历

这样就能很好的实现,大的数据块存储在磁盘上,索引表存储于内存中了。这种模型是不需要对原始数据集进行排序操作的,因为块与块之间是可以不连续的存放的。在原始数据产生前确定分多少块,以及每个块的存储位置(块间位置不连续,块内位置连续),这时每个块内的存储数据的范围也要确定,当新的数据到来的时候,就能确定要把这个数据放到哪个块中。

举个例子:

我想设计一个分块索引来查找数据,大体估算有3600个数据,所以根据算法最优(下面讲,暂且这么认为),设置60个块,每个块有60个记录。60个块就对应磁盘上的60个文件夹目录用来存储数据,这60个块的块间位置不连续。同时假设这3600个记录的关键字大小范围是1-3000,那么第一块就存储1-50的记录。来一个新纪录,如果关键字在1-50之间,就直接把它追加到第一块中。同时如果这个记录的关键字值大于索引表中的最大关键码,就对索引表中的最大关键字码更新。

分块索引表的平均查找长度分析

设有n个记录,被分成了m块,每块有t条记录。显然n=mxt。在索引表和块中的平均查找长度分别是Lb和Lw。

上面的分析中,在块间使用的也是顺序查找,因为块间是有序的,所以可以使用折半查找等快速的算法来提高效率。

http://blog.csdn.net/wtfmonking/article/details/17337703
http://blog.csdn.net/xiaoping8411/article/details/7706381

http://blog.csdn.net/xiaoping8411/article/details/7706376

http://blog.csdn.net/wangyunyun00/article/details/23464359

http://blog.csdn.net/fovwin/article/details/9077017

#define ILMSize 60;
#define MaxSize 3600;
//建立索引项结构
struct IndexItem
{
	int index;
	int start;
	int length;
};
//建立索引表
typedef struct IndexItem indexList[ILMSize];	//ILMSize为事先定义好的整型常量,大于等于索引项数目m
//建立原始数据的主表
int mainList[MaxSize];	//MaxSize为事先定义好的整型常量,大于等于主表中的记录的个数n

/*
*	输入:主表A,索引表B,索引表中索引项数目m,要搜索的元素elem
*	输出:找到的元素的下标
*/
int blockSearch(mainList A, indexList B, int m, int elem)
{
	for(int i = 0; i < m; i++)
	{
		if(B[i].index >= elem)
		{
			break;
		}
	}//for
	if(i == m)
	{
		return -1;	//查找失败
	}

	int endNum = B[i].start + B[i].length;
	for(int j = B[i].start; j < num; j++)
	{
		if(A[j] == elem)
		{
			break;
		}
	}//for
	if(j < num)
	{
		return j;
	}
	if(j == num)
	{
		return -1;
	}

}

  

时间: 2024-10-28 10:45:15

基础算法-查找:线性索引查找的相关文章

数据结构-查找-线性索引查找(对于无序顺序存储,建立索引快速查找)

1.索引 我们前面提到的几种高效查找方法都是基于有序的基础上的,但是实际上,很多数据集可能增长非常快.例如空间动态信息等,对于这样的查找表,我们若是保证记录全部按照当中某个关键字有序,其维护的时间代价非常高,所以这种数据通常是按照先后顺序存储. 数据结构的最终目的就是提高数据的处理速度,索引是为了加快查找速度而设计的一种数据结构.索引就是把一个关键字与他对应的记录相关联的过程. 一个索引由若干个索引项构成,每个索引项至少应包含关键字和其对应的记录在存储器中的位置等信息. 索引技术是组织大型数据库

基础算法-查找:折半查找

折半查找 又称为二分查找.这种查找方法要求查找表的数据是线性结构保存,并且还要求查找表中的数据是按关键字由小到大有序排列. 折半查找(二分查找)是一种简单而又高效的查找算法,其查找长度至多为㏒2n+1(判定树的深度),平均查找长度为㏒2(n+1)-1,效率比顺序查找要高,但折半查找只能适用于顺序存储有序表(如对线性链表就无法有效地进行折半查找). 经典非递归算法实现 int Binary_Search(int search_table[], int key, int low ,int high)

基础算法-查找:插值查找

算法描述 先来看一个实际问题:我们在一本英汉字典中寻找单词“worst”,我们决不会仿照对半查找(或Fibonacci查找)那样,先查找字典中间的元素,然后查找字典四分之三处的元素等等. 事实上,我们是在所期望的地址(在字典的很靠后的地方)附近开始查找的,我们称这样的查找为插值查找. 可见,插值查找不同于前面讨论的几种查找算法,前面介绍的查找算法是基于严格比较的,即假定我们对线性表中元素的分布一无所知(或称没有启发式信息). 然而实际中,很多查找问题所涉及的表满足某些统计的特点. 插值查找在实际

基础算法——查找

/************************************************************************* > File Name: search.cpp > Author: xinyang > Mail: [email protected] > Created Time: Tue 06 Oct 2015 03:22:35 PM CST ****************************************************

十大算法之线性查找

介绍: BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分 析,BFPRT可以保证在最坏情况下仍为线性时间复杂度.该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到o(n)的时间复杂 度,五位算法作者做了精妙的处理. 时间复杂度 O(N) 算法步骤: 1. 将n个元素每5个一组,分成n/5(上界)组. 2. 取出每一组的中位数,任意排序方法,比如插入排序. 3. 递归的调用selection算法查找上一步中所有中位数的中位数,设

大话数据结构—顺序表、有序表、线性索引查找

查找 根据给定的某个值,在查找表中确定一个其关键字(唯一的标识一个记录)等于给定值的数据元素或数据记录. 静态查找:只查找,不修改元素[线性表.顺序查找.二分查找] 动态查找:查找时,插入或者删除元素[二叉排序树] 顺序表查找 顺序查找(针对静态查找表),也叫线性查找O(n),从头开始遍历,直到最后一个记录. 优化:添加哨兵 //有哨兵的顺序查找 int foo(int *a,int n,int key) { int i; a[0]=key;//哨兵 i=n; while(a[i]!=key)

C/C++编程基础算法总结

使用王道机试指南的电子书也有几天的时间了,终于看完了第二章<经典入门>,下面就来总结回顾一下最常见的六种算法/问题,为下一步刷题打好坚实基础. 套路是:先概述这种题型,然后总结我学到的和易错点. ************************************题目都是九度OJ上的********************************************** 先提一句!时间复杂度!王道一直在提这一点,必须有根据题目中变量的范围来估算时间复杂度的意识. 一.排序问题 基本的冒

有动态示意图!程序员必须知道的10大基础算法讲解

目录: 算法一:快速排序算法 算法二:堆排序算法 算法三:归并排序 算法四:二分查找算法 算法五:BFPRT(线性查找算法) 算法六:DFS(深度优先搜索) 算法七:BFS(广度优先搜索) 算法八:Dijkstra算法 算法九:动态规划算法 算法十:朴素贝叶斯分类算法 算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n

基础算法之排序--快速排序

1 /************************************************************************************** 2 * Function : 快速排序 3 * Create Date : 2014/04/21 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不