查找一之顺序查找、二分查找、分块查找
1、概念:在一些有序的或无序的数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程叫做查找,也就是给定一个值,在查找表中确定一个关键字等于给定值的记录或数据元素。
2、平均查找长度(后期可能会增加)
3、查找长度分为成功和失败两种
4、顺序查找
1、主要思想:将查找值顺序逐个与结点值进行比较,相等即为查找成功,否则查找失败
2、代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | int SqSearch( int a[], int len, int e) { int i = 0; while (i < len && a[i]!= e) { i++; } if (i >= len) { return 0; //没有找到 } return i+1; //返回逻辑序号 } //时间复杂度:O(n) //查找成功平均长度 (n+1)/ 2 //查找失败平均长度 n / 2 |
5、二分查找(折半查找)
1、算法思想:每次比较中间值和待查找值得大小,然后更新范围,最后确定具体位置(重点:序列有序)
2、代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | int BinSearch( int a[], int len, int e) { int i = 0; int j = len-1; int mid; while (i <= j) { mid = j/2; if (e > a[mid]) { i = mid +1; } else if (e < a[mid]) { j = mid-1; } else return mid+1; } return -1; } //时间复杂度:log2n //ASL成功:1/n累加(times*deepth) //ASL失败:1/n累加(fails*deepth) //以二叉树了理解,排序写完会重新更新这一块内容 |
6、分块查找
1、算法思想:
1、把表长为n的线性表分成m块,前m-1块记录个数为 t = n / m t=n/m t=n/m,第m块的记录个数小于等于t;
2、块间有序,块中无序
3、建立索引表,其中记录每个块的起始位置以及最大元素
4、在增加元素的时候,根据索引表就知道在哪一块,把数据加到相应的块就好,因为块内无序;在查找时,索引表过大可以使用二分查找,会找到块在顺序查找,可能不会比二分查找好,但是不需要数据完全有序
2、代码1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | typedef struct { int key; int link; }IdxType; int IdxSearch(IdxType I[], int b, int a[], int len , int k) //b是分的块数,a是原数组,I是索引表,len是a数组的长度,k是需要查找值 { int s; int l; int r; int mid; s = (len+b-1)/b; //注意啊,确实是向下取整, l = 0; r = b-1; int i; while (l <= r) //对索引表进行二分查找 { mid = l+(r-l)/2; if (I[mid].key >= k) { r = mid -1; } else { l = mid +1; } } i = I[r + 1].link; while (i <= I[r+1].link + s -1 && a[i] !=k) //块内顺序查找 { ++i; } if (i <= I[r+1].link +s -1) { return i+1; //索引值没有越界的时候,就返回他的逻辑位置 } return -1; } |
3、代码2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include<stdio.h> struct indexBlock //定义块的结构 { int key; int start; int end; }indexBlock[4]; int search( int key, int a[]); int main() { int i; int j = -1; int k; int key; int a[] = {12,25,33,36,57,146,219,254,315,336,358,795,876,951,999}; printf ( "已知有一组数:\n" ); for (i = 0;i < 15;i++) { printf ( "%d " ,a[i]); if ((i+1)%5==0 && i < 14) { printf ( "|" ); } } printf ( "\n" ); //确定模块起始值和最大值 for (i = 0;i < 3;i++) { indexBlock[i].start = j+1; j++; indexBlock[i].end = j+4; j += 4; indexBlock[i].key = a[j]; //确定每一块的最大值?//直接赋值因为数组初始化的时候块的最后一个值最大值,违背了块内无序啊 printf ( "indexBlock[%d].start = %d\n" ,i,indexBlock[i].start); printf ( "indexBlock[%d].end = %d\n" ,i,indexBlock[i].end); printf ( "indexBlock[%d].key= %d\n" ,i,indexBlock[i].key); } // printf ( "input the num you want to search:" ); scanf ( "%d" ,&key); k = search(key,a); // if (k > 0) { printf ( "Find,Location is %d\n" ,k+1); } else { printf ( "Search Fail!\n" ); } return 0; } int search( int key, int a[]) { int i,startvalue; i = 0; while (i < 3 && key > indexBlock[i].key) { i++; } if (i >= 3) { return -1; } startvalue = indexBlock[i].start; while (startvalue <= indexBlock[i].end && a[startvalue] != key) { startvalue++; } if (startvalue > indexBlock[i].end) { startvalue = -1; } return startvalue; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)