目录
查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,例如编译程序中符号表的查找。
查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
查找算法分类:
1)静态查找和动态查找;
注:静态或者动态都是针对查找表而言的。动态表指查找表中有删除和插入操作的表。
2)无序查找和有序查找。
无序查找:被查找数列有序无序均可;
有序查找:被查找数列必须为有序数列。
平均查找长度(Average Search Length,ASL):需和指定key进行比较的关键字的个数的期望值,称为查找算法在查找成功时的平均查找长度。
对于含有n个数据元素的查找表,查找成功的平均查找长度为:ASL = Pi*Ci的和。
Pi:查找表中第i个数据元素的概率。
Ci:找到第i个数据元素时已经比较过的次数。
-
顺序查找
说明:顺序查找适合于存储结构为顺序存储或链接存储的线性表。
基本思想:顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。
复杂度分析:
查找成功时的平均查找长度为:(假设每个数据元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;
当查找不成功时,需要n+1次比较,时间复杂度为O(n);
所以,顺序查找的时间复杂度为O(n)。
-
实现代码
int direct_find(int *arr, int src_num, int len) { int i = 0; if (NULL == arr|| len <0) { puts("Error input arguements."); return -1; } for (i = 0; i < len; ++i) { if (src_num == arr[i]) { return i; } } return NO_FIND; }
-
二分查找
说明:元素必须是有序的,如果是无序的则要先进行排序操作。
基本思想:也称为是折半查找,属于有序查找算法。用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
复杂度分析:最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n);
注:折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。
-
实现代码
int BinarySearch(int* arr, int src_num, int left, int right) { if (NULL == arr || left < 0 || right < 0) { puts("Error input arguements."); return -1; } int mid = (left + right) / 2; if (src_num == arr[mid]) { return mid; } else if (arr[mid] < src_num) { return BinarySearch(arr, src_num, mid + 1, right); } else if (arr[mid] > src_num) { return BinarySearch(arr, src_num, left, mid - 1); } }
-
测试代码
/********************************************************************************* * Copyright: (C) 2020 shx * All rights reserved. * * Author: tianjincheng <[email protected]> * ********************************************************************************/ #include <iostream> #include <string> using namespace std; const int MAX_SIZE = 10; const int NO_FIND = -0xff; int BinarySearch(int* arr, int src_num, int left, int right); int direct_find(int *arr, int src_num, int len); int main(int argc, char** argv) { int pos = 0; int arr[10] = {1,2,3,4,5,6,7,8,9,10}; pos = direct_find(arr, 101, -10); if (pos >= 0) { printf("Find src_num in the list, and the pos = %d.\n", pos); } else if (NO_FIND == pos ) { puts("No such num.\n"); } system("pause"); return 0; } int direct_find(int *arr, int src_num, int len) { if (NULL == arr|| len <0) { puts("Error input arguements."); return -1; } int i = 0; for (i = 0; i < len; ++i) { if (src_num == arr[i]) { return i; } } return NO_FIND; } int BinarySearch(int* arr, int src_num, int left, int right) { if (NULL == arr || left < 0 || right < 0) { puts("Error input arguements."); return -1; } int mid = (left + right) / 2; if (src_num == arr[mid]) { return mid; } else if (arr[mid] < src_num) { return BinarySearch(arr, src_num, mid + 1, right); } else if (arr[mid] > src_num) { return BinarySearch(arr, src_num, left, mid - 1); } }