一.二分算法:
对于一个普通数组,我们当然只能遍历全数组。但对于一个有序数组,可以用类似二分法,每次缩小一半的区间长度。考虑最差的情况:n-->n/2-->n/4....所以最差时间复杂度为o(logn)
二分查找的泛型情况:
考虑数组:0 0 0 0 1 1 1 1 1 1 ;现查找第一个1的位置。
如果mid指针指向0时候,意味着要查找的1在mid后面,故head=mid+1;
如果mid指针指向1时候,因为mid的1也有可能就是第一个1,所以应该调整tail=mid;
如果头尾指针在交界面,经过计算知不会出现bug。
二分思维:
数组和函数是没有本质区别的。二者都是一种映射关系。所以其实我们将单调数组外推到函数,可以运用到单调的函数。(时间换空间,空间换时间)。
所以总结二分算法的条件:
1.数组有序或者函数单调。
2.有f[x]==y的映射关系,需要完成给出y反求x的过程。
代码实现:
数组查找:
int bineary_search(int*arr,int n,int x){
int head=0,tail=n-1,mid;//注意以后默认左闭右开。
while(head<=tail){
mid=(head+tail)/2;
if(arr[mid]==x)return mid;
else if(arr[mid]<x)head=mid+1;
else tail=mid-1;
}
return -1;
}
int main() {
int x,arr[10]={1,2,3,4,5,7,9,13,15,17};
scanf("%d",&x);
if(x==-1)return 0;
int ans=bineary_search(arr,10,x);
if(ans!=-1)printf("The index is %d",ans);
return 0;
}
函数计算:
#include <stdio.h>
#define min(a,b) ((a)<(b)?(a):(b))
double f(double x){
if(x>=0)x-=(min(x,3000))*0.03;
if(x>3000)x-=(min(x,12000)-3000)*0.1;
if(x>12000)x-=(min(x,25000)-12000)*0.2;
if(x>25000)x-=(min(x,35000)-25000)*0.25;
if(x>35000)x-=(min(x,55000)-35000)*0.3;
if(x>55000)x-=(min(x,80000)-55000)*0.35;
if(x>80000)x-=(x-80000)*0.45;
return x;
}//这里给出从x->>y的函数关系,这就相当于数组中的数组下标i-->a[i];
double bineary_search(double y){
double min=0;double max=100000;
while((max-min)>=1e-4)//只需要达到一个误差即可,注意和数组的区别。因为函数是连续的数组!数组只是间断点)
{
double mid=(min+max)/2;
if(f(mid)<y)min=mid;
else max=mid;
}
return max;
}
int main() {
double y;
scanf("%lf",&y);
double x=bineary_search(y);
printf("The pre is %f",x);
return 0;
}
二.跳跃表:
跳跃表的性质:1.头尾节点分别是正负无穷,也即保证元素在头尾节点之间插入。
2.维护跳跃表元素的有序性。
查找操作:以跳跃表当前位置下一位(也就是右边一位)与带查找元素x比较:
如果比x大,那就向下一步;如果比x小,就向右走一步。
插入操作:(关键:待插入节点的前一个结点)
非常抽象的插入操作,假设我要插入6层高度的10,先遍历查找10,标注经过的元素。如图,那么画红圈部分就是每一层需要连接10这栋”楼“的元素。
哈希函数:将任意类型的数组映射到数组下标(从高维空间到低维空间的映射规则)
哈希冲突:有两个不同的元素映射到同一位置。
发生哈希冲突时,冲突处理:1.开放定址法:根据当前的地址通过固定的规则重新得到另一个地址。2.再哈希法:重新实现一个哈希函数。
3.建立公共溢出区。
4.拉链法:每个位置都维护一个链表。
传统哈希表:存储空间与元素强相关。
布隆过滤器:存储空间与元素若相关。
如果布隆过滤器判断某个元素没有出现过,那就是一定没有出现过。
如果它判断出现过,只能说是大概率没有出现过。(是一个概率)
比如,数据a-->1,5,7 数据b-->1,2,5.
对于数据c-->2,5,7.
所以其实没有出现过,但误判了。
哈希表的代码实现:(用拉链法)因为是用拉链法,所以应该是节点结构和哈希表结构。