数据结构 插值查找 斐波那契查找
来源:互联网 发布:不能说的夏天 知乎 编辑:程序博客网 时间:2024/06/09 21:19
数据结构 插值查找 斐波那契查找
二分查找(折半查找):
1、它属于有序查找算法, 元素必须是有序的,如果是无序的则要先进行排序操作。
2、基本思想:
用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,
这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
3、复杂度分析:
最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n);
插值查找算法:
1、基于二分查找算法,属于有序查找,它将查找点的选择改进为自适应选择,从而提高查找效率
二分查找的查找点计算:
mid=(low+high)/2
插值查找的查找点:
mid=low+(key-a[low])/(a[high]-a[low])*(high-low)
它根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,间接地减少了比较次数,提高查找效率。
2、插值查找算法适合于表长较大,而关键字分布又比较均匀的查找表
3、复杂度分析:
查找成功或者失败的时间复杂度均为O(log2(log2n))
斐波那契数列(递归方法定义):
数学定义上满足F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2) (n>=2)—从第三个数开始,后边每一个数都是前两个数的和,该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)的数列。
斐波那契查找:
它与二分查找相似(是二分查找的一种提升算法),也属于一种有序查找算法,它是根据斐波那契序列的特点对有序表进行分割的,通过在数列中选择查找点进行查找,提高查找效率。
算法思想:
在斐波那契数列找一个等于略大于查找表中元素个数的数F[k],将原查找表扩展为长度为Fk,完成后进行斐波那契分割,
即F[k]个元素分割为前半部分F[k-1]个元素,后半部分F[k-2]个元素,找出要查找的元素在那一部分并递归,直到找到该元素。
算法描述:
开始将key值与第F(k-1)位置的记录进行比较(即mid=low+F(k-1)-1),比较结果也分为三种
1、key == 查找表a[mid],mid位置的元素即为所求
2、key > 查找表a[mid],low=mid+1,k-=2;
low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,可递归应用斐波那契查找。
3、key < 查找表a[mid],high=mid-1,k-=1。
low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,可递归应用斐波那契查找。
复杂度分析:
最坏情况下,时间复杂度为O(log2n),且其期望复杂度也为O(log2n)
public class fbsearch { public final static int MAXSIZE = 10; public static boolean runFlag = true; //斐波那契数列 public static int[] fibonacci() { int[] f = new int[10]; int i = 0; f[0] = 1; f[1] = 1; for (i = 2; i < MAXSIZE; i++) { f[i] = f[i - 1] + f[i - 2]; } return f; } public static int fibonacciSearch(int[] data, int key) { int low = 0; int high = data.length - 1; int mid = 0; int k = 0; // 斐波那契分割数值下标 int i = 0; int[] f = fibonacci(); // 构造查找所需的斐波那契数列 // 获取斐波那契分割数值下标 while (data.length > f[k] - 1) { k++; } int[] temp = new int[f[k] - 1]; // 创建临时扩展表 for (int j = 0; j < data.length; j++) { temp[j] = data[j]; } // 补充表满足表长度等于f[k] - 1 for (i = data.length; i < f[k] - 1; i++) { temp[i] = temp[high]; // 以原表的最后一个元素的值扩充表 } if(runFlag){ runFlag = false; System.out.print("斐波那契 数列:\n"); for (int j : f) { System.out.print(j + " "); } System.out.println(); System.out.println("查找表:"); for (int j : data) { System.out.print(j + " "); } System.out.println(); System.out.println("扩充后查找表:"); for (int j : temp) { System.out.print(j + " "); } System.out.println(); } // 表的全部元素 = 表的前半部分 + 表的后半部分 // f[k] = f[k-1] + f[k-2] while (low <= high) { mid = low + f[k - 1] - 1; //获取表的中间点 if (temp[mid] > key) {//查找前半部分f[k-1] high = mid - 1; k = k - 1; //更新斐波那契数列k } else if (temp[mid] < key) {//查找后半部分f[k-2] low = mid + 1; k = k - 2; //更新斐波那契数列k } else { // 如果为真则找到相应的位置 if (mid <= high) { return mid; } else { // 查找到补充的元素,返回high位置的元素 return high; } } } return -1; } //二分查找, 非递归版本 public static int BinarySearch1(int a[], int value, int n) { int low, high, mid; low = 0; high = n-1; while(low<=high) { mid = (low+high)/2; if(a[mid]==value) return mid; if(a[mid]>value) high = mid-1; if(a[mid]<value) low = mid+1; } return -1; } //二分查找,递归版本 public static int BinarySearch2(int a[], int value, int low, int high) { int mid = low+(high-low)/2; if(a[mid]==value) return mid; if(a[mid]>value) return BinarySearch2(a, value, low, mid-1); if(a[mid]<value) return BinarySearch2(a, value, mid+1, high); return mid; } //插值查找 public static int InsertionSearch(int a[], int value, int low, int high) { int mid = low+(value-a[low])/(a[high]-a[low])*(high-low); if(a[mid]==value) return mid; if(a[mid]>value) return InsertionSearch(a, value, low, mid-1); if(a[mid]<value) return InsertionSearch(a, value, mid+1, high); return mid; } public static void main(String[] args) { // TODO Auto-generated method stub int[] data = { 5, 15, 22, 25, 31, 39, 42, 45 }; int search = 31; System.out.println("查找表:"); for (int j : data) { System.out.print(j + " "); } System.out.println(); int position = InsertionSearch(data, search, 0, data.length-1); System.out.println("插值查找:" + search + " 该元素的位置:" + position); System.out.println(); position = fibonacciSearch(data, search); System.out.println("斐波那契查找:" + search + " 该元素的位置:" + position); search = 55; position = fibonacciSearch(data, search); System.out.println("斐波那契查找:" + search + " 该元素的位置:" + position); }}
程序输出:
查找表:
5 15 22 25 31 39 42 45
插值查找:31 该元素的位置:4
斐波那契 数列:
1 1 2 3 5 8 13 21 34 55
查找表:
5 15 22 25 31 39 42 45
扩充后查找表:
5 15 22 25 31 39 42 45 45 45 45 45
斐波那契查找:31 该元素的位置:4
斐波那契查找:55 该元素的位置:-1
- 数据结构 插值查找 斐波那契查找
- 数据结构之查找——折半查找、插值查找、斐波那契查找
- 二分查找,插值查找,斐波那契查找
- 查找算法小结:顺序查找、 二分查找、斐波那契查找 、插值查找
- 静态查找(顺序查找,折半查找,插值查找,斐波那契查找)
- 考研路_数据结构_查找2_插值查找和斐波那契查找
- 看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)
- 顺序查找:二分查找,斐波那契查找,插值查找
- 查找(顺序查找、插值查找和斐波那契查找)
- 简单查找算法之折半查找、插值查找、斐波那契查找
- 有序表查找(二分查找,插值查找,斐波那契查找)
- 【查找】二分查找、插值查找、斐波那契查找
- 折半查找、插值查找和斐波那契查找
- 有序向量:二分查找&斐波那契查找&插值查找
- 折半查找、插值查找以及斐波那契查找
- 常见的查找算法(顺序、二分、插值、斐波那契查找,哈希查找)
- 斐波那契查找(数据结构)
- 数据结构 斐波那契查找
- Hibernate Criteria条件Restrictions.or查询 循环多个or条件
- VC++ 防火墙 Win7 XP MFC
- 可变参数args应用于printf原型
- java synchronized
- canvas画一个图片,并实现点击按钮上移下移左移右移放大缩小
- 数据结构 插值查找 斐波那契查找
- java注解方式(不用xml)配置web框架spring+SpringMVC
- CentOS 5.4 配置本地YUM源
- KNN分类程序(C++版本)
- Spark源码(1)- Master的启动(standalone)
- Windows Socket编程示例-TCP示例程序
- qq提供的聊天接口
- Android Studio统计项目代码量
- Nginx Access Log日志统计分析常用命令