数据结构与算法—二分查找
Posted 为了维护世界和平_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法—二分查找相关的知识,希望对你有一定的参考价值。
目录
二分查找
针对的是一个有序的数据集合,查找思想类似于分治思想。
每次通过跟区间中的元素对比,将待查找的区间缩小为原来的一半,直到找到数据为止,或区间缩小到0
时间复杂度
查找速度O(logn),非常高效
N, n/2 , n/4 , … n/2^k
经过K次区间缩小操作,时间复杂度O(K)
n/2^k = 1 -> k = log2n 时间复杂度O(logn)
42亿个数据用二分查找,最多32次找到
程序设计要点
1,循环退出条件 low<=high
2、mid取值 mid=(low+high)/2 不佳,如果low,high比较大,之和可能溢出。
low+(high-low)/2 或者 low+((high-low)>>1)
3、low,high值更新
low=mid+1,high=mid-1
可以使用递归实现
局限性
1、依赖的顺序结构,数组。
链表是不可以的
2、有序的数据
动态的插入,删除,使用二叉树
3、数据量太小,不适合二分查找
4、数据量太大,不适合。数据连续存储困难。1GB数据太大
实例:如何在1000万个整数快速查找某个整数,内存限制100MB
每个数据大小是8字节,将1000万数据存在数组中,内存占用80MB。
8*10000000/1024/1024 = 76.2939MB
先排序,再用二分查找。
散列表和二叉树好像能解?实际上不行的,内存空间不够,节点指针占用空间。
二分查找的变形
1、查找第一个等于给定元素的值
2、查找最后一个等于给定元素的值
3、查找第一个大于等于给定元素的值
4、查找最后一个小于等于给定元素的值
实例分析
查找IP地址归属地,IP区间
假设有12万条这样的IP区间与归属地对应关系,如何快速定位出一个IP地址的归属地?
因为IP地址区间不经常更新,先将12万条数据,按照起始地址IP 从小到大排列(IP地址转化为32位的整型数)
在有序数组中,查找最后一个小于等于某个给定值的元素。
通过二分查找,找到最后一个起始IP小于等于这个IP地址区间,然后,检查这个IP是否在这个IP区间内,如果在,就取出对应的归属地显示,如果不在则返回没找到。
二分查找能解决的问题,大部分倾向于用散列表或者二叉查找树。即使二分查找在内存使用上更节省,但毕竟内存如此紧缺的情况并不多。
二分查找更适合在“近似”查找问题,如二分查找的变体边界查找的处理。如果用散列表、二叉树、比较难实现。
二叉搜索实现(不考虑重复条件)
#include<stdio.h>
#include<stdlib.h>
typedef int(*binarch_search)(int *arr,int size,int val);
//使用递归实现
int binary_search_rec(int *arr,int size,int val)
int mid = size / 2;
int idx;
if(arr[mid] == val)
return mid;
if(!mid)
return -1;
if(arr[mid]<val)
idx = binary_search_rec(arr+mid+1,size - mid -1,val);
if(idx !=-1)
idx +=mid+1;
else
idx = binary_search_rec(arr,mid,val);
return idx;
//使用迭代
int binary_search_iter(int *arr,int size,int val)
int low,mid;
int high = size - 1;
while(low < high)
mid = (low + high)/2;
if(arr[mid] == val)
return mid;
if(arr[mid] < val)
low = mid + 1;
else
high = mid -1;
void iter_test(binarch_search binary_search_fun)
int arr[10] = 1, 4, 5, 9, 12, 19, 21, 28, 31, 36;
int idx ;
idx = binary_search_fun(arr,10,12);
if(idx != -1)
printf("find 12 at %d\\n",idx);
else
printf("12 not find in arr\\n");
//实现方法不同,参数相同
//回调函数使用
void main()
iter_test(binary_search_iter);
iter_test(binary_search_rec);
以上是关于数据结构与算法—二分查找的主要内容,如果未能解决你的问题,请参考以下文章