@skiery
[总结自王道视频,希望对大家找工作有所帮助]
查找
定义:在数据集合中寻找满足某些条件的数据元素过程。
0.1查找表
用于查找的数据集合成查找表:
1.查询某个元素是否存在;
2.查询某个元素的属性;
1 2属于静态查找表,常用方式:顺序查找表、折半查找
3.动态查找表:二叉排序树、二叉平衡树
0.2关键字
数据元素中某个可以唯一标识该元素的数据项;
0.3平均查找长度(ASL)
在查找过程中,一次查找的长度指需要比较的关键字的次数,而平均查找长度是所有查找过程中进行关键字的比较次数的平均值。
ASL = ΣPi*Ci n为查找表中元素个数,Pi是查找第i个元素的概率,一般为等概率查找,Pi的为1/n,Ci为找到第i个元素需要比较的关键字次数,即查找长度。
1.1顺序查找
主要用于在线性表中进行查找,从查找表的一端开始,顺序扫描查找表,依次将扫描到的关键字和带查找的值key进行比较,相等成功,扫描结束未发现元素,查找失败。
int search1(int A[],int n,int key){
for(int i=0;i<n;i++){
if(A[i] == key){
return i+1;
}
}
return 0;
}
int search2(int A[],int n,int key){
if(A[0]==key){
return 1;
}
A[0] = key;
while(A[i]!=key){
i--;
}
if(i==0) return 0;
return i+1;
}
ASL:
1.成功:(n+1)/2
2.失败:n
时间复杂度:O(n)
1.2折半查找
算法思路:首现给定key与表中间元素的关键字比较,相等则查找成功,返回位置;失败则缩小查找范围,在缩小的范围内继续进行折半查找,重复直到找到位置,或确定没有该元素,查找失败。
适用范围:有序的顺序表
int Binary_Search(int A[],int n,int key){
int low = 0;int high = n-1;int mid;
while(low<=high){
mid = (low+high)/2;
if(A[mid] == key){
return mid+1;
}
else{
if(A[mid]>key) high = mid-1;
else low = mid+1;
}
}
return 0;
}
折半查找判定树:可以将查找过程化为折半查找二叉树,查找的比较次数就是从根节点到该节点经历的结点数
N个结点的完全二叉树高度为log(2(N+1)),所以折半查找时间复杂度为O(logN)。
ASL:成功:直接求所有比较成功次数的期望,即每个点所在层数的和除以总点数;
失败:直接求在每个位置失败所需的次数,再除以失败的情况的和,得到结果。
1.3分块查找
按索引查找,需要额外建立一个索引表来存储索引,每个索引对应表中每一块,并且每个块间都是有顺序的。
(1)块间折半查找,块内顺序查找:
ASL = ASL(折半)+ASL(顺序) = [log2(b+1)] + (1+s)/2
(2)块间块内均顺序查找:
ASL = ASL(块间顺序)+ASL(块内顺序) = (1+b)/2 + (1+s)/2
2.1二叉排序树
二叉排序树(Binary Search Tree),也叫二叉搜索树,是一颗空树,或者具有以下性质的树:
(1)若左子树不空,则左子树上所有结点值均小于其根结点的值;
(2)若右子树不空,则右子树上所有结点值均大于其根结点的值。
左小右大
与根结点比较,小于根结点向左子树找,大于根结点向右子树查找。
2.1.1查找关键字
BitNode *BST_Search(BitNode *t,int key)){
if(t==NULL) return NULL;
else{
if(t->key==key) return t;
else if(key<t->key)return BST_Search(t->lchild,key);
else return BST_Search(t->rchild,key);
}
}
2.1.2插入关键字
1)空树:直接插入;
2)树非空:检测是否有重复关键字结点;
1.存在:不插入,直接返回插入失败;
2.不存在:检查根结点值和待插入关键字值的大小关系递归插入左右子树
int BST_Insert(BitNode* &t,int k){
if(t==NULL){
t = (BitNode*)malloc(sizeof(BitNode));
t->key = k;
t->lchild = t-rchild = NULL;
return 1;
}
else if(t->key == k) return 0;
else if(t->key>k) return BST_Insert(t->lchild,k);
else return BST_Insert(t->rchild,k);
}
2.1.3删除关键字
1.删除叶子节点:直接删除;
2.只有一个孩子节点:用孩子节点替代父节点;
3.有两个子节点:找到左子树的最大节点作为前驱节点;找到右子树的最小节点作为后继节点,
散列表
散列表:根据给定的关键字计算出关键字在表中的地址的数据结构,建立了关键字和存贮地址之间的一种直接映射关系。
散列函数:一个把查找表中的关键字映射成为该关键字对应的地址的函数,几位Hash(key)=Addr
会用即可,这里面试和应用不会这么详细,有兴趣大家自己看吧~