zoukankan      html  css  js  c++  java
  • java数据结构之有序表查找

    这篇文章是关于有序表的查找,主要包括了顺序查找的优化用法、折半查找、插值查找、斐波那契查找;

    顺序优化查找:效率极为底下,但是算法简单,适用于小型数据查找;

    折半查找:又称为二分查找,它是从查找表的中间开始查找。查找结果只需要找其中一半的数据记录即可。效率较顺序查找提高不少。比较适用与静态表,一次排序后不在变化;

    插值查找:与折半查找比较相似,只是把中间之mid的公式进行了变换将mid = (low+high)/2;换成了mid = low + (high - low) * (key - sum[low]) / (sum[high] - sum[low]);

                  插值查找的效率比折半查找的效率又要高出不少,比较适用与表长较大,而关键字又分布得比较均匀的表查找;

    斐波那契查找:是利用了黄金分割的原理来进行查找,平均性能要由优于折半查找,但是如果时最坏的情况,则效率低于折半查找(要查找的关键字一直比较靠近黄金分割较长的那一                             段),但是运算比较简单,只有最简单的加减运算;

    代码实现:

      1 /**
      2  * 查找
      3  * 2016/5/1
      4  * 
      5  **/
      6 package cn.Link;
      7 
      8 public class Search {
      9     public static void main(String [] args){
     10         int n = 10;         //数组长度
     11         int key = 18;        //查找关键数
     12         int sum[] = new int[n];//有序数组
     13 
     14         for(int i = 0;i < n;i++ ){
     15             sum[i] = i*2;
     16         }
     17         System.out.println("本程序由于查找值为key的数组下标,如果返回负数,则表示没有找到,");
     18         //打印sum数组
     19         System.out.print("sum数组:");
     20         for(int u: sum){
     21             System.out.print(u+" ");
     22         }
     23         System.out.println("
    要查找的数为:"+key);
     24         
     25         int  result = Sequential_Serach(sum,n,key);
     26         System.out.println("
    顺序优化查找结果:"+result);
     27         result = Binary_Serach(sum,n,key);
     28         System.out.println("折半查找查找结果:"+result);
     29         result = Interpolation_Serach(sum,n,key);
     30         System.out.println("插值查找查找结果:"+result);
     31         result = Fibonacci_Serach(sum,n,key);
     32         System.out.println("斐波那契查找结果:"+result);
     33 
     34     }
     35 
     36 
     37 
     38     //顺序优化查找
     39     public static int Sequential_Serach(int sum[],int n, int key){
     40         if(key >sum[n-1] || key < sum[0])
     41             return -1;    //sum为从小到大排列,如果key大于sum[n-1]或小于sum[0]则肯定找不到
     42         
     43         int i;
     44         int sum_1 = sum[0];  //记录sum首位值,用以在程序结束时还原
     45         sum[0] = key;
     46         i = n-1;
     47         while(sum[i] != key){
     48             i--;
     49         }
     50         sum[0] = sum_1;
     51         if(i !=0 ){
     52             return i;
     53         }else{
     54             return -1;
     55         }
     56     }
     57 
     58     //折半查找
     59     public static int Binary_Serach(int sum[],int n,int key){
     60         if(key >sum[n-1] || key < sum[0])
     61             return -1;    //sum为从小到大排列,如果key大于sum[n-1]或小于sum[0]则肯定找不到
     62         
     63         int low = 0;
     64         int high = n-1;
     65         int mid ;
     66         while(low <= high){
     67             mid = (low+high)/2;
     68             if(key < sum[mid]){
     69                 high = mid -1;
     70             }else if(key > sum[mid]){
     71                 low = mid +1;
     72             }else{
     73                 return mid;
     74             }
     75         } 
     76         return -1;
     77     }
     78 
     79     //插值查找  与折半查找只有mid的得到结果一行代码不同  优势:查找表长比较大,而关键字分布又比价均匀的查找表时平均性能比折半查找要好
     80     public static int Interpolation_Serach(int sum[],int n,int key){
     81         
     82         if(key >sum[n-1] || key < sum[0])
     83             return -1;    //sum为从小到大排列,如果key大于sum[n-1]或小于sum[0]则肯定找不到
     84         if(sum[0] == sum[n-1])  return  0;  //首数和尾数相等  这是一个所有数都想等的数组 没有这一步的话会发生除零错误
     85         
     86         int low = 1;
     87         int high = n-1;
     88         int mid ;
     89         while(low <= high){
     90             mid = low + (high - low) * (key - sum[low]) / (sum[high] - sum[low]);
     91             if(key < sum[mid]){
     92                 high = mid -1;
     93             }else if(key > sum[mid]){
     94                 low = mid +1;
     95             }else{
     96                 return mid;
     97             }
     98         } 
     99         return -1;
    100     }
    101 
    102     //斐波那契查找  平均性能要由优于折半查找,但是如果时最坏的情况,则效率低于折半查找如key=2
    103     public static int Fibonacci_Serach(int sum[],int n,int key){
    104         if(key >sum[n-1] || key < sum[0])
    105             return -1;    //sum为从小到大排列,如果key大于sum[n-1]或小于sum[0]则肯定找不到
    106         
    107         int low, high, mid, i, k;
    108         low = 0;
    109         high = n-1;
    110         k = 0;
    111         int F[] = new int[n];
    112         F[0] = 0;
    113         F[1] = F[2] = 1;
    114         for(i = 3;i < n;i++){       //建立一个斐波那契数列,理论上这个数组是无限长的
    115             F[i] = F[i-1] + F[i-2];
    116         }
    117         while(n > F[k]-1){          //计算n位于斐波那契数列的位置
    118             k++;
    119         }
    120         
    121         int[] sum_1 = new int[F[k]-1];         //增加数组的长度
    122         for(i = 0;i < F[k]-1;i++){      //将不满的数值补全
    123             if(i < n){
    124             sum_1[i] = sum[i];
    125             }else{
    126                 sum_1[i] = sum[n-1];
    127             }
    128         }
    129         
    130         while ( low <= high ){
    131             mid = low+F[k-1]-1;
    132             if(key < sum_1[mid]){
    133                 high = mid-1;
    134                 k = k-1;
    135             }else if(key > sum_1[mid]){
    136                 low = mid + 1;
    137                 k = k-2;
    138             }else{
    139                 if(mid < n ){
    140                     return mid;        //找到了这个数
    141                 }else{
    142                     return n-1;        //如果差找到的数在sum[n-1]以后返回sum最后一个数
    143                 }
    144             }
    145         }
    146         return -1;
    147     }
    148 }
    149 
    150     
  • 相关阅读:
    mockito测试final类/static方法/自己new的对象
    flink 1.11.2 学习笔记(5)-处理消息延时/乱序的三种机制
    linux查找操作
    分析MongoDB架构案例
    legend3---bootstrap modal框出现蒙层,无法点击modal框内容(z-index问题)
    legend3---laravel报419错误
    laravel自定义中间件实例
    laravel中间件Middleware原理解析及实例
    git: Failed to connect to github.com port 443: Timed out
    记忆规律
  • 原文地址:https://www.cnblogs.com/snail-lb/p/5452017.html
Copyright © 2011-2022 走看看