25、静态查找表(顺序表、索引顺序表、静态树表、折半查找)
2、静态查找表:对查找表只进行查找操作。动态查找表:不仅进行查找操作,而且在查找过程中还伴随着插入(查找的数据元素不在表中时)、删除某个数据元素的操作。
3、关键字(key):是数据元素(或记录)的某个数据项的值,用它可标识(识别)一个数据元素(或记录)。
4、平均查找长度(ASL):需和给定值进行比较的关键字个数的期望。
基本思想:先建立索引(最大(最小)关键字表)。要查找关键字为key的元素,先按折半查找获得key对应记录所在的块,再按线性(顺序)查找在块中找到key对应的记录。
我们前面的几种方法都是假定查找是等概率然情况下进行的。实际中,如果概率是不等的,情况又如何呢?即使按折半查找中判断树进行,也不一定最优。使查找性能最佳的判定树是其带权内路径长充之和PH值
int IdxSerch(SSTable ST,IdxType index[],int b,KeyType key)
{ //分块查找关键字为k的记录,索引表为index[0..b-1]
if(index[mid].key<key) low=mid+1;
for(i=index[low].link;(i<=index[low].link+s-1)&&(i<=ST.length);i++)
//printf(" %d %d",ST.elem[i].key,key);
if(ST.elem[i].key==key) return i;
ElemType *elem;//数据元素存储空间基址,建表时按实际升序分配,0号单元
BiTNode *lchild,*rchild; // 左右孩子指针
typedef BiTree SOSTree; // 次优查找树采用二叉链表的存储结构
printf("Please input the number of da
printf("Please input the %d's da
ST.elem=(ElemType*)calloc(N+1,sizeof(ElemType));//动态生成N个数据单元空间,
printf("Please input the %d's da
printf("Please input the %d's item:\n",i);
if(ST.elem[j].key<ST.elem[0].key)
{ // 操作结果: 构造一个含n个数据元素的静态按关键字非降序查找表ST
int Search_Seq(SSTable ST,KeyType key)
for(i=ST.length;ST.elem[i].key!=key;--i) ;
int Search_Bin(SSTable ST,KeyType key)
if(ST.elem[mid].key==key) return mid;
else if(key<ST.elem[mid].key) high=mid-1;
int IdxSerch(SSTable ST,IdxType index[],int b,KeyType key)
{ //分块查找关键字为k的记录,索引表为index[0..b-1]
if(index[mid].key<key) low=mid+1;
for(i=index[low].link;(i<=index[low].link+s-1)&&(i<=ST.length);i++)
//printf(" %d %d",ST.elem[i].key,key);
if(ST.elem[i].key==key) return i;
// 初始条件: 静态查找表ST存在。操作结果: 销毁表ST
int IdxSerchIt(SSTable &ST,KeyType s)
printf("input the MaxIndex of index table:\n");
scanf("%d",&MaxIndex); //注意对,MAxIndex的选取有讲究,不然会出
index[j].key=ST.elem[ince].key;
if(ince<ST.length) ince+=ST.length/MaxIndex;
i=IdxSerch(ST,index,MaxIndex,s);
int SecondOptimal(BiTree &T, ElemType R[],int sw[],int low,int high)
if(fabs(dw-sw[j]-sw[j-1])<min)
if(!(T=(BiTree)malloc(sizeof(BiTNode))))
SecondOptimal(T->lchild,R,sw,low,i-1);
SecondOptimal(T->rchild,R,sw,i+1,high);
void FindSW(int sw[],SSTable ST)
{ // 按照有序表ST中各数据元素的Weight域求累计权值表sw
sw[i]=sw[i-1]+ST.elem[i].item;
int CreateSOSTree(SOSTree &T,SSTable ST)
int sw[ST.length+1]; // 累计权值表sw
FindSW(sw,ST); // 按照有序表ST中各数据元素的Weight域求累计权值表sw
SecondOptimal(T,ST.elem,sw,1,ST.length);
int Search_SOSTree(SOSTree &T,KeyType key)
{ // 在次优查找树T中查找关键字等于key的元素。找到则返回OK,否则返回FALSE
//CreateSOSTree(T,ST);//创建静态查找树
//Search_SOSTree(T,s);//静态查找树查找
printf("%d: %d",i,ST.elem[i].key);
折半查找算法的计算复杂性可以用二叉树来进行分析。我们把当前查找区间的中间位置上的记录作为根。左子表和右子表中的记录分别作为根的左子树和右子树。由此得到的二叉树,称为描述二分查找的判定树或比较树。
![25、静态查找表 - 墨涵 - 墨涵天地 25、静态查找表 - 墨涵 - 墨涵天地](http://img241.ph.126.net/5ewSeGTzErxhnGc6ryFrZg==/1391612284858347554.png)
折半查找只适用有序顺序存储结构,不适于线性链表结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的记录。折半查找特别适用于那种一经建立就很少改动,而又经常需要查找的线性表。
由于分块查找实际上是两次查找过程,所以分块查找的平均查找长度是:查找索引表确定给定值所在块内的平均查找长度ASLb与在块的查找关键值的平均查找长度ASLk之和。即ASL=ASLb+ASLk。
其查找过程类似折半查找。其平均查找长度和Logn成正比。当在记录中查找概率不等时,可用次优查找树。
1、void *calloc(unsigned num, unsigned size),分配一块内存,num和size分配内存的数量参数,实际字节等于num*size。头文件为alloc.h。