查找:
基本概念:
-
查找:找到符合条件的数据元素(记录)
-
查找表:
- 由同一类型的数据元素(记录)组成
- 静态查找表:只需要查找操作
- 动态查找表:除了查找,还需要增加/删除数据元素
-
关键字:唯一标识数据元素的数据项
-
查找算法的效率评价:
- 查找长度:在查找运算中,需要对比关键字的次数
- 平均查找长度ASL:所有查找过程中进行关键字的比较次数的平均值
- 通常考虑查找成功/失败两种情况下的ASL
(一)顺序查找:又叫线性查找,通常用于线性表
- 时间复杂度:O(n)
typedef struct{ //查找表的数据结构(顺序表)
ELemType *elem; //动态数组地址
int TableLen; //表的长度
}SSTable;
//顺序查找
int Search_Seq(SSTable ST, ElemType key){
int i;
for(i = 0; i < ST.TableLen && ST.elem[i] !=key; ++i)
//查找成功,则返回元素下标,查找失败,则返回-1
return i == ST.TableLen ? -1 : i;
}
- 顺序查找的优化(对有序表):当当前查找的元素大于目标元素时,就可以跳出循环了
- 时间复杂度:O(n)
- 总结:
(二)折半查找(二分查找):仅适用于有序的顺序表
typedef struct{ //查找表的数据结构(顺序表)
ElemType *elem; //动态数组基址
int TableLen; //表的长度
}SSTable;
//折半查找(当前是升序排列)
int Binary_Search(SSTable L, ElemType key){
int low = 0, high = L.TableLen-1,mid;
while(low < high){
mid = (low + high)/2; //取中间位置
if(L.elem[mid] == key)
return mid; //查找成功则返回所在位置
else if(L.elem[mid] > key)
high = mid -1; //从前半部分继续查找
else
low = mid+1; //从后半部分继续查找
}
return -1; //查找失败,返回-1
}
- 折半查找的判定树,一定是平衡二叉树,只有最下面一层是不满的。
- 元素个数为n时,树高h=[log2(n+1)]
- 总结:
折半查找在大部分情况下比顺序查找更优秀