数据结构(Java)-查找算法(顺序、二分、插值)

java中,我们常用的查找有四种:

   1) 顺序(线性)查找

   2) 二分查找/折半查找

   3) 插值查找

   4) 斐波那契查找

一、线性查找(略)

//线性查找 傻瓜式查找
    public static int linerSearch(Integer[] arr,Integer findVal){
       for(int i=0;i<arr.length;i++){
           count++;
           if(arr[i].equals(findVal)){
               return i;
           }
       }
       return -1;
    }

二、二分查找

        注意有三个辅助变量:mid、left、right,mid指的是序列中间的元素。每次用mid元素与查找值findVal比较大小,如果arr[mid]>findVal,就调整查找范围为(left,mid-1);如果arr[mid]<findVal,就调整查找范围为(mid+1,right),继续重复比较的操作,直到找到findVal或者未找到。找到时返回mid索引,未找到返回-1.

        这里是递归的二分查找:

 public static int binarySearch(Integer[] arr,Integer findVal,int left,int right){
        count++;
        //递归的终止条件之二:找不到该元素
        if(left > right || arr[0]>findVal || arr[arr.length-1]< findVal ) {
            return -1;
        }
        //没有查找完该序列的时候
        int mid = (left + right)/2;
        int midVal = arr[mid];
        //判断midVal与findVal的大小关系
        if(findVal > midVal) {//(1)向右递归,查找findVal;
            return binarySearch(arr,findVal, mid+1, right);
        }else if(findVal < midVal) {
            return binarySearch(arr, findVal,left, mid-1);//(2)向左递归,查找findVal;
        }else {//(3)findVal == midVal,表明找到了待查找的findVal,返回 mid 的索引值;
            return mid;
        }
    }

        这是迭代的二分查找:

public static int binarySearch(Integer[] arr,Integer findVal){
        //最基本的条件都不满足,退出去
        if(arr[0]>findVal || arr[arr.length-1]< findVal ) {
            return -1;
        }else {
            int left = 0, right = arr.length - 1;
            //判断条件,若越界了就说明没找到
            while (left <= right) {
                count++;
                int mid = (left + right) / 2;
                if (findVal.equals(arr[mid])) return mid;
                else if (findVal > arr[mid]) left = mid + 1;
                else right = mid - 1;
            }
            //没找到就返回-1
            return -1;
        }
    }

 

三、插值查找

        1) 插值查找算法类似于二分查找,不同的是插值查找每次从 自适应mid 处开始查找。
        2) 将折半查找中的求 mid 索引的公式 , low 表示左边索引 left, high 表示右边索引 right.
key
就是前面我们讲的  findVal
        3) int mid = low + (high - low) * (key - arr [low]) / ( arr [high] - arr [low])  ;/* 插值索引* /
        对应前面的代码公式:
         int mid = left + (right – left) * (findVal – arr[left]) / (arr[right] – arr[left])
 public static int insertValueSearch(Integer[] arr,Integer findVal,int left,int right){
        count++;
        //递归的终止条件之二:找不到该元素
        if(left > right || arr[0]>findVal || arr[arr.length-1]< findVal ) {
            return -1;
        }
        //没有查找完该序列的时候,与二分查找的区别也就在这里,优化了mid的选取
        int mid = left+(right-left)*(findVal-arr[left])/(arr[right]-arr[left]);
        int midVal = arr[mid];
        //判断midVal与findVal的大小关系
        if(findVal > midVal) {//(1)向右递归,查找findVal;
            return binarySearch(arr,findVal, mid+1, right);
        }else if(findVal < midVal) {
            return binarySearch(arr, findVal,left, mid-1);//(2)向左递归,查找findVal;
        }else {//(3)findVal == midVal,表明找到了待查找的findVal,返回 mid 的索引值;
            return mid;
        }
    }

注意事项

1) 对于数据量较大, 关键字分布比较均匀 的查找表来说,采用 插值查找 , 速度较快 .
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]-1 F[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 位置的值即可。

        while(n>fib(k)-1) k++;

暂时不看了,太麻烦,没什么意思

 五、测试

  public static int count=0;
    @Test
    public void testBinarySearch(){
        Integer[] arr = init();
        Arrays.sort(arr);
        print(arr);
        Integer findVal=new Random().nextInt(1000);
        System.out.println("查找值:"+ findVal);
        System.out.println("1、线性查找: 索引:"+ linerSearch(arr, findVal) +" , "+"搜索次数:"+count);
        count=0;
        System.out.println("2、二分查找: 索引:"+ binarySearch(arr, findVal, 0, arr.length - 1) +" , "+"搜索次数:"+count);
        count=0;
        System.out.println("3、插值查找: 索引:"+ insertValueSearch(arr, findVal, 0, arr.length - 1) +" , "+"搜索次数:"+count);
        count=0;

    }




0 2 3 3 4 7 7 8 11 11 13 17 18 18 19 19 21 22 23 24 26 28 28 31 31 31 31 32 32 32 32 33 33 33 33 34 34 34 36 36 37 37 38 38 40 41 41 44 46 46 46 47 48 48 48 52 54 54 55 55 58 59 60 61 62 63 63 65 68 68 71 71 73 73 74 75 76 76 76 76 79 80 81 81 82 82 83 86 87 89 90 91 91 91 92 96 96 96 97 97 98 99 101 103 103 104 104 105 106 106 109 109 109 109 114 114 115 117 118 118 119 120 120 120 120 122 123 123 123 124 125 128 128 131 133 133 133 134 135 137 137 139 139 140 140 142 143 143 144 145 145 145 147 148 149 149 149 150 151 151 151 152 152 154 156 157 159 160 161 162 163 163 163 164 165 167 169 171 172 172 174 174 174 176 177 177 178 179 179 179 183 183 184 184 186 187 189 192 192 196 197 199 199 200 200 201 202 203 204 205 207 209 209 211 213 214 214 216 218 219 221 222 223 224 224 225 225 225 226 227 228 230 230 233 233 234 235 237 237 239 240 240 242 243 244 245 246 246 246 248 248 249 251 252 252 253 254 257 258 259 259 261 261 262 263 264 265 266 267 269 270 270 270 272 276 277 277 277 279 279 279 281 282 283 283 285 286 288 289 290 292 293 294 295 295 296 296 297 298 301 302 304 307 307 310 311 312 314 314 314 316 316 317 319 319 319 320 320 320 320 322 323 323 324 324 326 326 327 329 330 330 333 334 336 338 338 339 339 339 339 340 340 340 342 346 346 347 347 348 349 355 356 359 360 361 362 365 365 365 367 367 367 369 376 376 376 376 377 378 378 379 381 382 384 384 384 386 386 386 388 389 390 390 391 391 394 395 399 399 399 401 401 402 403 403 404 404 405 405 407 407 408 408 410 410 411 412 412 415 416 416 419 420 421 422 422 423 423 423 425 426 427 427 427 429 429 429 431 432 432 432 433 433 435 435 435 436 436 437 442 442 444 446 447 447 449 449 452 452 455 457 460 462 463 464 467 467 468 468 469 469 470 472 473 474 474 476 477 477 478 479 479 482 483 485 485 487 488 488 489 491 492 492 493 493 494 496 496 496 498 499 499 500 502 503 503 504 504 505 506 507 507 509 510 510 511 512 513 516 517 517 518 519 521 522 522 523 526 526 527 528 528 532 533 533 536 536 536 540 544 545 546 548 548 549 552 553 553 553 553 553 555 557 557 558 560 560 560 561 561 562 563 563 566 567 570 571 571 574 575 575 576 576 576 576 579 579 579 582 582 583 584 584 588 591 591 592 592 594 594 594 594 598 600 601 603 603 605 605 610 610 612 615 615 617 619 619 621 621 621 623 623 624 626 627 627 627 627 627 627 627 631 632 632 632 633 633 635 635 637 637 639 641 641 641 644 645 645 646 646 646 646 647 647 648 649 649 649 650 650 652 653 654 654 654 655 655 656 656 657 657 658 660 660 660 662 664 664 666 667 668 668 670 673 673 673 675 677 679 680 681 681 682 682 682 683 685 685 685 685 685 686 688 688 689 689 691 693 693 694 694 694 694 695 695 696 697 697 697 698 698 699 699 699 699 700 706 707 708 713 714 714 715 716 717 717 717 717 717 717 718 719 722 724 724 725 726 728 728 730 730 731 731 732 732 733 734 734 735 735 735 736 736 738 738 740 741 741 741 743 744 744 744 746 746 746 748 750 750 754 755 756 756 756 758 759 761 762 766 767 770 770 773 776 776 776 777 777 779 779 781 781 783 785 788 789 789 789 790 792 793 794 794 795 796 797 799 800 800 801 802 803 804 804 804 804 806 806 807 809 809 809 810 810 810 811 813 813 813 814 814 815 815 817 818 826 826 826 827 828 828 829 830 830 830 830 832 833 833 833 833 833 833 835 835 836 836 837 838 838 841 842 842 843 843 845 847 848 848 848 849 852 852 854 856 857 858 858 860 862 863 863 865 866 867 867 867 867 867 868 870 872 874 874 874 874 876 876 879 883 883 885 886 886 887 887 888 888 888 889 892 893 896 896 898 900 900 900 902 902 903 903 904 905 906 906 910 910 911 912 914 915 916 916 917 919 919 920 920 921 923 925 928 929 931 931 932 934 934 935 939 940 941 941 942 943 943 944 946 946 948 948 950 952 953 954 955 955 955 956 956 957 957 959 959 959 960 961 961 962 964 965 967 968 969 969 970 972 972 973 973 977 980 983 983 983 983 985 985 985 987 992 993 995 995 996 998 998 998 999 
查找值:973
1、线性查找: 索引:979 , 搜索次数:980
2、二分查找: 索引:980 , 搜索次数:8
3、插值查找: 索引:979 , 搜索次数:3

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值