算法思想:
算法背景
有时候,可能会遇到这样的表:整个表中的元素未必有序,但若划分为若干块后,每一块中的所有元素均小于(或大于)其后面块中的所有元素。我们称这种为分块有序。
对于分块有序表的查找
首先,我们需要先建立一个索引表,索引表中为每一块都设置–索引项,每一个索引项都包含两个内容:
该块的起始地址
该块中最大(或最小)的元素
显然,索引表是按关键字递增或递减次序排列的。如下图所示:
查找过程
在前面建立的索引表的基础上,我们查找一个关键字需要两个步骤:
在索引表中查找,目的是找出关键所属的块的位置。这里如果索引表较大的话,可以采用折半查找。(也可以顺序查找)
进入该块中,使用简单顺序表查找算法进行关键字查找。
算法分析
这种带索引表的分块有序表查找的时间性能取决于两步查找时间之和:如前面所述,第一步可以采用简单顺序查找和折半查找之一进行。第二步只能采用简单顺序查找,但由于子表的长度较原表的长度小。因此,其时间性能介于顺序查找和折半查找之间。
实现方法:
// zfd.cpp : 定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 100
#define MIN 20
typedef struct
{
int key;
int link;
}block;
typedef block IDX[MIN];
typedef struct
{
int element;
}OA;
typedef OA OAR[MAX];
int indexsearch(IDX a,int min,OAR b,int max ,int key)
{
int low = 0;
int bb = max / min;
int high = min - 1;
while (low <= high)
{
int mid = (low+high) / 2;
if (a[mid].key < key)
low = mid + 1;
else
high = mid - 1;
}
//if (high == min)
// return -1;
int i = a[high + 1].link;
for (; i <a[high + 1].link+ bb; i++)
{
if (b[i].element == key)
return i;
}
return -1;
}
int main()
{
int keydata;
int m = 25, n = 5;
IDX idx = { {14,0},{34,5},{66,10},{85,15},{100,20} };
OAR oar = { 8,14,6,9,10,22,34,18,19,31,40,38,54,66,46,71,78,68,80,85,100,94,88,96,87 };
cout << "please input the search data:" << endl;
cin >> keydata;
int result=indexsearch(idx,n,oar,m,keydata);
if (result == -1)
{
cout << "can not find the number!" << endl;
}
else
cout << "could find the number,the position is " << result + 1 << endl;
system("pause");
return 0;
}