查找,在一组记录集合中,找到关键码值等于给定值的某个记录,或找到关键码值符合特定条件的某些记录的过程,也叫检索。
一、查找表,是由同一类型的数据元素(或记录)构成的集合。
二、提高查找效率的方法:1、预排序;2、建立索引;3、散列技术(不允许出现重复关键码,不适合进行范围查询);
三、平均查找长度(也叫平均检索长度),检索过程中对关键码的比较次数。(ASL,Average Search Length)
四、对查找表查询、检索操作的称为静态查找;插入、删除操作的称为动态查找;
五、比较式查找,特点是,记录在表中的位置和其关键字间不存在确定的关系,查找过程为给定值依次和各个关键字进行比较,查找的效率取决进行比较的关键字个数
1、顺序查找,等概率下,查找成功查找长度 (n+1)/2,设置监哨岗的情况下,查找失败查找长度n+1次,平均查找长度 (n+1)/2 < ASL < n+1
1 #include <stdio.h> 2 3 /* 定义数组 */ 4 #define MAXSIZE 100 5 typedef int ElementType; 6 typedef struct LNode *List; 7 8 struct LNode{ 9 ElementType Element[MAXSIZE]; 10 int Length; 11 }; 12 13 /* 顺序查找 */ 14 int SequentialSearch (List Tbl, ElementType K) 15 { /*在表Tbl[1]~Tbl[n]中查找关键字为K的数据元素*/ 16 int i; 17 Tbl->Element[0] = K; /*建立哨兵*/ 18 for(i = Tbl->Length; Tbl->Element[i]!= K; i--); 19 return i; /*查找成功返回所在单元下标;不成功返回0*/ 20 } 21 22 int main() 23 { /* 定义静态表变量及指针 */ 24 struct LNode L; 25 List Tbl = &L; 26 27 /* 静态表赋值 */ 28 int N = 7; 29 for(int i=1; i<=N; ++i){ 30 Tbl->Element[i] = i; 31 } 32 Tbl->Length = N; 33 34 /* 查找是否成功, 成功返回下标 */ 35 printf("%d", SequentialSearch(Tbl, 6)); 36 return 0; 37 }
2、二分法查找,数据元素的关键字满足有序(比如:小到大) 并且是连续存放(即顺序存储,数组),那么可以进行二分查找;查找成功时查找次数不会超过判定树的深度 , n个结点的判定树的深度 为[log2n]+1;二分查找只适合关键字有序并且顺序存储的查找表;
1 #include <stdio.h> 2 3 /* 定义数组 */ 4 #define MAXSIZE 100 5 typedef int ElementType; 6 typedef struct LNode *List; 7 8 struct LNode{ 9 ElementType Element[MAXSIZE]; 10 int Length; 11 }; 12 13 /* 二分查找 */ 14 int BinarySearch ( List Tbl, ElementType K) 15 { /*在表Tbl中查找关键字为K的数据元素*/ 16 int left, right, mid, NotFound = -1; 17 left = 1; /*初始左边界*/ 18 right = Tbl->Length; /*初始右边界*/ 19 while ( left <= right ) 20 { 21 mid = (left+right)/2; /*计算中间元素坐标*/ 22 if( K < Tbl->Element[mid]) right = mid-1; /*调整右边界*/ 23 else if( K > Tbl->Element[mid]) left = mid+1; /*调整左边界*/ 24 else return mid; /*查找成功,返回数据元素的下标*/ 25 } 26 return NotFound; /*查找不成功,返回-1*/ 27 } 28 29 int main() 30 { /* 定义静态表变量及指针 */ 31 struct LNode L; 32 List Tbl = &L; 33 34 /* 静态表赋值 */ 35 int N = 7; 36 for(int i=1; i<=N; ++i){ 37 Tbl->Element[i] = i; 38 } 39 Tbl->Length = N; 40 41 /* 查找是否成功, 成功返回下标 */ 42 printf("%d", BinarySearch(Tbl, 7)); 43 return 0; 44 }
3、二叉查找树(又叫二叉排序树,二叉搜索树);
六、散列查找,也叫哈希查找,https://blog.csdn.net/qq_25579889/article/details/50466204
1、哈希函数,预先知道所查关键字在表中的位置,记录表中位置和关键字之间的确定关系,可以直接找到该结点;一般情况下,在关键字与记录在表中的存储位置之间建立一个函数关系,以h(key)作为关键字为key的记录在表中的位置,通常称为这个函数h(key)为哈希函数;散列函数一般应考虑两个因素,一个是简单,一个是关键字对应的地址空间分布均匀,以尽量减少冲突;装填因子,设散列表空间大小为m,填入表中元素个数为n,则称n/m为散列表的装填因子;散列方法的存储对关键字是随机的,不便于顺序查找关键字,也不适合于范围查找,或最大值最小值查找;
2、数字关键字的散列函数构造:直接定址法( h(key) = key - 1990 ,h(key) = a*key + b),除留余数法( h(key) = key mod p,p = TableSize,p一般取小于TableSize的素数 ),数字分析法( h(key) = atoi(key+7) , char *key ),折叠法,平方取中法;
字符关键字的散列函数构造:ASCII码加和法,前3位字符移位法( h(key) = (key[0]*27^2+key[1]*27+key[2]) mod TableSize),移位法;
Index Hash(const char *Key, int TableSize) { unsigned int h = 0; /*散列函数值,初始化为0*/ while(*Key != '