查找表是由同一类型的数据元素(或记录)构成的集合。由于“集合”中的元素之间存在着松散的关系,因此查找表是一种用用灵便的结构。
查找:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或(记录)。
关键字:用来标识一个数据元素(或记录)的某个数据项的值。
查找表可以分为两类
静态查找表
仅作查询
动态查找表
可以作插入和删除
查找算法的评价指标:
顺序表或线性链表表示的静态查找表
表内元素之间无序
在顺序表中查找值为key的数据元素(从最后一个元素开始比较)
int Search_Seq(SSTable ST,KeyType key) { for(i = ST.length;i>=1;--i) { if(ST.R[i].key==key) { return i; } } return 0; }
其他形式:
int Search_Seq(SSTable ST,KeyType key) { for(i = ST.length;ST.R[i].key!=key;--i) { if(i<=0) { break; } } if(i>0) { return 0; } else return 0; }
int Search_Seq(SSTable ST,KeyType key) { ST.R[0].key = key; for(i=ST.length;ST.R[i].key!=key;--i) { if(i<=0) { break; } if(i>0) { return i; } else return 0; } }
查找表存储记录原则——按照查找概率高低存储
记录的查找概率无法测定时如何提高查找效率?
方法——按查找概率动态调整记录顺序:
int Search Bin(SSTable ST,KeyType key) { low = 1;high = ST.length;//置区间初值 while(low<=high) { mid = (low+high)/2; if(ST.R[mid].key == key) return mid;//找到待查元素 else if(key<ST.R[mid].key)//缩小查找区间 high = mid-1;//继续在前半区进行查找 else low = mid+1;//继续在后半区进行查找 } return 0;//顺序表重不存在待查元素 }
递归折半
int Search_Bin(SSTable ST,keyType key,int low,int high) { if(low>high) return 0; mid = (low+high)/2; if(key == ST.elem[mid].key) return mid; else if(key<ST.elem[mid].key) { ...//递归,在前半区间进行查找 } else { ...//递归,在后半区间进行查找 } }
二叉排序树或是空树,或是满足如下性质的二叉树
中序遍历非空的二叉排序树所得到的数据元素序列是一个按关键字排列的递增有序序列。
算法:
typedef struct { KeyType key;//关键字项 InfoType otherinfo;//其他数据域 }ElemType
typedef struct BSTNode { ElemType data;//数据域 struct BSTNode *lchild,*rchild;//左右孩子指针 }BSTNode,*BSTree; BSTree T;//定义二叉排序树T
若查找的关键字等于根结点,成功
否则
在左右子树上的操作类似
BSTree SearchBST(BSTree T,KeyType key) { if(!T||KEY==T->data.key) return T; else if(key<T->data.key) return SearchBST(T->lchild,key);//在左子树重继续查找 else return SearchBST(T->rchild,key);//在右子树重继续查找 }
二叉排序树上查找某关键字等于给定值的结点过程,其实就是走了一条从根到该结点的路径。
含有n个结点的二叉排序树的平均查找长度和树的形态有关
最好情况:树的深度为:[log2n] + 1;与折半查找重的判定树相同。(形态比较均衡)。O(log2n)
最坏情况:插入的n个元素从一开始就有序,——变成单支树的形态!
此时树的深度为n,ASL = (n+1)/2,查找效率与顺序查找情况相同:O(n)
问题:如何提高形态不均衡的二叉排序树的查找效率?
解决方法:做“平衡化”处理,即尽量让二叉树的形态均衡。
高度:子树的层数
定义
为了方便起见,给每个结点附加一个数字,给出该结点左子树与右子树的高度差。这个数字称为结点的平衡因子(BF)
如果在一棵AVL树种插入一个新结点后造成失衡,则必须重新调整树的结构,使之恢复平衡。
平衡调整的四种类型,LL,LR,RL,RR
与LR型同理
记录的存储位置与关键字之间存在对应关系。
散列方法(杂凑法)
散列函数(杂凑函数):散列方法种使用的转换函数。
散列表(杂凑表):按照上述思想构造的表。
冲突:不同的关键码映射到同一个散列地址
key1 !=key2,但是H(key1) = H(key2)
同义词:具有相同函数值的多个关键字
在散列查找方法种,冲突是不可能避免的,只能尽可能减少。
直接定址法
优点:以关键码key的某个线性数值为散列地址,不会产生冲突
缺点:要占用连续的地址空间,空间效率低。
数字分析法
平方取种法
折叠法
除留余数法
随机数法
开放定址法(开地址法)
链地址法(拉链法)
再散列法(双散列函数法)
建立一个公共溢出区
ASL取决于:
装填因子=表中填入的记录数/哈希表的长度