小言_互联网的博客

查找算法---插值查找算法and斐波那契查找算法

399人阅读  评论(0)

插值查找原理介绍:

       1)插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找

       2)将折半查找中的求mid 索引的公式, low表示左边索引, high表示右边索引.

      3)int midindex =low + (high-low) * (key - arr(low) / (arr[high]-arr[low); /"插值索引*/

      4)举例说明插值查找算法1-100的数组


  
  1. package com.alibaba.search;
  2. public class InsertValueSearch {
  3. public static void main(String[] args) {
  4. int[] arr= new int[ 100];
  5. for ( int i = 0; i < arr.length; i++) {
  6. arr[i]=i+ 1;
  7. }
  8. int index = insertValueSearch(arr, 0, arr.length- 1, 5);
  9. System.out.println(index);
  10. }
  11. //插值算法方法
  12. public static int insertValueSearch(int arr[],int left,int right,int findVal){
  13. System.out.println( "插值查找的次数···");
  14. //优化 防止mid 越界
  15. if (left>right||arr[ 0]>findVal||findVal>arr[arr.length- 1]){
  16. return - 1;
  17. }
  18. //请mid
  19. int mid=left+(right-left)*(findVal-arr[left])/(arr[right]-arr[left]);
  20. int midVal=arr[mid];
  21. if (findVal>midVal){ //说明应该向右递归
  22. return insertValueSearch(arr,mid+ 1,right,findVal);
  23. } else if (findVal<midVal){
  24. return insertValueSearch(arr, 0,mid- 1,findVal);
  25. } else{
  26. return mid;
  27. }
  28. }
  29. }

      插值查找的注意事项:

             1)对于数据量较大,关键字分布较均匀的查找表来说,采用插值查找速度快

             2)关键字分布不均匀的情况下,该方法不一定比折半查找要好

斐波那契(黄金分割算法)查找基本介绍:

       1)黄金分割点是指把一条线段分割为两部分,使其中一部分与全长之比等于另一部分与这部分之比,取其前三位数字的近似值,是0.618,由于按此比例设计的造型十分美丽,因此称为黄金分割,也称为中外比,这是一个神奇的数字,会带来意想不到的效果。

       2)斐波那契数列{1,1,2,3,5,8,13,21,34,55}发现斐波那契数列的两个相邻数的比例,无限接近黄金比例0.618

       斐波那契(黄金分割算法)原理:

              斐波那契查找原理与前两种相似,仅仅改变了中间节点(mid)的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即mid=low+F(k-1)-1  (F代表斐波那契数列),如下图所示:

             

       对F[k-1]-1的理解:

            1) 由斐波那契数列F[k]=F[k-1]+ F[k-2]的性质,可以得到(F[k]-1)= (F[k-1]-1) +(F[k-2]-1) +1.该式说明:只要顺序表的长度为F[k]-1,则可以将该表分成长度为F[k-1]-1F[k-2]-1的两段,即如上图所示。从而中间位置为mid=low+F(k-1)-1

            2)类似的,每一子段也可以用相同的方式分割

            3)但顺序表长度n不一定刚好等于F[k]-1,所以需要将原来的顺序表长度n增加至F[k]-1.这里的k值只要能使得F[k]-1恰好大于或等于n即可,由以下代码得到,顺序表长度增加后,新增的位置(从n+1到F[k]-1位置),都赋为n位置的值即可

       斐波那契查找应用案例:

            请对一个有序数组进行斐波那契查找{1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示“没有这个数“。

            代码实现:


  
  1. package com.alibaba.search;
  2. import java.util.Arrays;
  3. public class FibonacciSearch {
  4. public static int maxSize= 20;
  5. public static void main(String[] args) {
  6. int arr[]={ 1, 8, 10, 89, 1000, 1234};
  7. int index = fibSearch(arr, 89);
  8. System.out.println( "下标为"+index);
  9. }
  10. //因为后面我们mid=low+F(k-1)-1,需要使用斐波那契数列,因此我们先要获一个斐波那契数列
  11. //非递归得到斐波那契数列
  12. public static int[] fib(){
  13. int[] f= new int[maxSize];
  14. f[ 0]= 1;
  15. f[ 1]= 1;
  16. for ( int i = 2; i <maxSize; i++) {
  17. f[i]=f[i- 1]+f[i- 2];
  18. }
  19. return f;
  20. }
  21. //编写斐波那契数列查找算法
  22. /**
  23. *
  24. * @param a 数组
  25. * @param key 我要查找的值
  26. * @return 返回对应的下标
  27. */
  28. //非递归方式
  29. public static int fibSearch(int[] a,int key){
  30. int low= 0;
  31. int high=a.length- 1;
  32. int k= 0; //斐波那契分割数值的下标
  33. int mid= 0; //存放mid值
  34. int[] f=fib(); //获得fib数列
  35. //获得斐波那契分割数值的下标
  36. while (high>f[k]- 1){
  37. k++;
  38. }
  39. //因为f[k] 的值可能大于 a的长度,因此我们需要使用Arrays类,构造一个新的数组,并指向a
  40. int[] temp= Arrays.copyOf(a,f[k]);
  41. //实际上我们需要a数组的最后的数填充temp
  42. for ( int i=high+ 1;i<temp.length;i++){
  43. temp[i]=a[high];
  44. }
  45. //使用while循环,找到我们的数
  46. while (low<=high){ //就可以退出
  47. mid=low+f[k- 1]- 1;
  48. if (key<temp[mid]){ //像数组的左边查找
  49. high=mid- 1;
  50. k--;
  51. } else if (key>temp[mid]){
  52. low=mid+ 1;
  53. k-= 2;
  54. } else{
  55. if (mid<=high){
  56. return mid;
  57. } else{
  58. return high;
  59. }
  60. }
  61. }
  62. return - 1;
  63. }
  64. }

 


转载:https://blog.csdn.net/weixin_44076260/article/details/106170904
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场