分块查找(索引顺序表查找)

分块查找:分块查找又称索引顺序查找,它是顺序查找的一种改进方法。

方法描述:将n个数据元素“按块有序”划分为m块(m<=n)。每一块中的数据元素不必有序,但块与块之间必须“按块有序”,即第1快中的任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都小于第3块中的任一元素,……

图示分块如下:


操作步骤:

1、先选取各快中的最大关键字构成一个索引表

2、查找分两部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后在已确定的快中用顺序法进行查找。

分块查找平均查找长度:

设长度为n的表均匀地分成b块,每块含有s个记录,则b=n/s;

顺序查找所在块,分块查找的平均查找长度=(b+1)/2 + (s+1)/2 = (n/s+s)/2+1;

折半查找所在块,分块查找的平均查找长度=log2(n/s+1)+s/2;

优点:在表中插入或删除一个记录时,只要找到该记录所在块,就在该块中进行插入或删除运算(因快内无序,所以不需要大量移动记录)。

缺点:增加了一个辅助数组的存储空间和将初始表分块排序的运算。

性能:介于顺序查找和二分查找之间。

示例(block.c):

#include 
#include 

#define MAX 3
#define MAXSIZE 18


typedef int ElemType;
typedef struct IndexItem{
	ElemType index;
	int start;
	int length;
}IndexItem;
IndexItem indexlist[MAX];

ElemType MainList[MAXSIZE] = {22, 12, 13, 8, 9, 20, 33, 42, 44, 38, 24, 48, 60, 58, 74, 49, 86, 53};

int sequential(IndexItem indexlist[], ElemType key)
{
	int index;
	if(indexlist[0].index >= key) return 1;
	for(index = 1; index <= MAX; index++){
		if((indexlist[index-1].index < key)&&(indexlist[index].index >= key))	
				return index+1;
	}
	return 0;
}

int mainsequential(ElemType MainList[], int index, ElemType key)
{
	int i, num=0;
	for(i = 0; i < index-1; i++){
		num += indexlist[i].length;	
	}
	for(i = num; i < num+indexlist[index-1].length; i++){
		if(MainList[i] == key) return i+1;	
	}
	return -1;
}

int 
main(void)
{
	indexlist[0].index = 22;
	indexlist[0].start = 1;
	indexlist[0].length = 6;
	indexlist[1].index = 48;
	indexlist[1].start = 7;
	indexlist[1].length = 6;
	indexlist[2].index = 86;
	indexlist[2].start = 13;
	indexlist[2].length = 6;
	int index = sequential(indexlist, 38);
	printf("index = %d.\n", index);
	int mainindex = mainsequential(MainList, index, 38);
	printf("mainindex = %d.\n", mainindex);
	return 0;
}

编译:gcc block.c

运行:./a.out

测试结果:

index = 2.
mainindex = 10.


你可能感兴趣的:(数据结构)