数据结构
第七章 查找
线性表查找
- 静态查找: 对查找表不做修改
- 动态查找: 查找同时进行操作
查找算法的评价指标
关键字平均比较次数,也称平均比较长度ASL(Average Search Length)
顺序表中查找e的数据元素
int LocateELem(SSTable L,ElemType key)
{
for(int i=0 ;i < L.lengrh;i++)
if(L.R[i].key==key )return i+1;
}
//改进版
int Search_Seq(SSTable ST,KeyType key){
ST.r[0].key=key;//key设为哨兵
for(i = ST.length; ST.T[i].key != key ; i--);
return i;
}
时间复杂度为O(n)
二分法查找
int Search_Bin(SSTable ST,KeyType key){
low = 1;high = ST.length;
while(low<=high){
mid = (low+high)/2;
if(key == ST.R[mid].key)return mid;
else if(key<ST.R[mid].key)high = mid-1;
else low=mid+1;
}
return 0;
}
时间复杂度O(logn)
分块查找
- 索引表进行二分查找
- 进入分块表进行顺序查找
树表查找
二叉排序树
对于任意节点 左子树任意节点小于根节点 右子树任意节点大于等于根节点
//二叉排序树的遍历
//查找失败返回空指针
BSTreeSearchBST(BSTree T,KeyType key){
if((!T)||key == T->data.key)return T;
else if
(key<T->data.key)return BSTreeSearchBST(T->lchild,key)
else return BSTreeSearchBST(T->rchild,key)
}
//二叉树的插入
s = new BSTNode;
s->data = e;
s->lchild = s->rchild = NULL;
if(!p)T= s;
// 插入 来源网络
BinaryTreeNode* Insert(BinaryTreeNode* BST, int x){
if(!BST){
BST = new BinaryTreeNode(x);
}
else{
if(x < BST->val)
BST->left = Insert(BST->left, x);
else if(x > BST->val)
BST->right = Insert(BST->right, x);
}
return BST;
}
时间复杂度 最好O(logn) (与二分法查找的判定树类似) 最坏:(n+1)/2
删除
//第四种情况
q = p ; s= p->lchild;
while(s->rchild){q = s; s = s->rchild;}
p->data=s->data;
if(q!=p)q->rchild = s->lchild;
else q->lchikd = s->lchild;//重接*q的左子树
free(s);
平衡二叉树
平衡因子: 对于所有节点节点 其左子树深度减右子树深度 等于0 -1 或1的树
平衡二叉树插入节点
插入会造成失衡 ——> 进行平衡旋转
哈希表
基本思想 :记录的存储位置与关键字之间存在对应关系,loc(i)=H(keyi)->哈希函数
优点:查找速度快O(1)与元素位置无关
相关术语
哈希方法(凑杂法):选取某个函数,以该函数关键字记录存储位置,并按此存放;
查找时,由同一个函数确定给定值k计算地址,将k与地址中元素关键码进行比对,确定查找是否成功
哈希函数:哈希方法中使用的转换函数
哈希表:按上述思想构造的表
冲突:不同关键码映射到同一个哈希地址
构造哈希函数考虑的因素
- 计算哈希函数所用的时间
- 关键字长度
- 哈希表大小
- 关键字分布状况
- 查找频率
处理冲突的方法
缺点:会产生“聚集”现象 降低查找效率