• 实验三-总结博客


    实验三-查找与排序-3

    参考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中补充查找算法并测试
    提交运行结果截图

    斐波那契查找

    • 1.斐波那契数列
      斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)。

    • 2.实现思路
      我认为斐波那契查找和二分查找的区别不大,唯一的区别是二分查找的划分是对半分,而斐波那契查找是根据斐波那契数列进行的划分。但我们知道斐波那契查找的算法复杂度依旧是O(log 2 n ),而且实现还很复杂,所以斐波那契查找相较于二分查找的好处是在每次计算mid的值的时候避免了"除法",只是涉及到了"加法和减法",而除法的运算本身就比加减法更加占用时间。
      如何进行查找。之所以斐波那契查找避免了除法,是因为我们一开始构造了一个斐波那契数列,每次划分只需要从数列中拿出相应的两个数就行。斐波那契数列:1、1、2、3、5、8、13、21、34、55、89……从第三个数开始,每个数等于前两个数的和,巧妙利用这一点我们在每次比较后对于mid的赋值就不必像二分查找mid = (first + last ) / 2,而是mid = first+fib[idex-1]-1,fib是我们构造的一个斐波那契数列,正是要利用斐波那契数列的特点进行分割,我们就必须根据要进行查找的数组来从fib数组中确定一个数m.这里会出现两种情况:(1)数组长度刚好符合fib数列中的某个数;(2)fib数组找不到恰当的数,这时候就需要将原数组进行扩充,我们采用重复填入最后一个数。如果m = fib[n],那么第一次划分就将数组分为两个部分它们分别含有fib[n-1]和fib[n-2]个元素,然后进行比较,再根据比较的结果再对数组进行划分。

        public static Comparable FibonacciSearch(Comparable[] data, Comparable target) {
            int idex = 0;
            int[] fib = SetFibonacci();
            while (data.length>fib[idex]){
                idex++;
            }
            Comparable[] fibdata = new Comparable[fib[idex]];
            ;
            for (int i = 0;i<fibdata.length;i++){
                if (i<data.length){
                    fibdata[i] = data[i];
                }
                else
                    fibdata[i] = data[data.length-1];
            }
            int first=0;
            int last = fibdata.length-1;
            int mid = 0;
            while (first<= last){
                    mid = first+fib[idex-1]-1;
                    if (fibdata[mid].compareTo(target)>0){
                        last = mid;
                        idex = idex-1;
                    }
                    else if (fibdata[mid].compareTo(target)<0){
                        first = mid;
                        idex = idex-2;
                    }
                    else {
                        if (mid<=last)
                            return mid;
                        else
                            return last;
                    }
            }
            return -1;
        }
        //构造Fibonacci数列
        public static int[] SetFibonacci() {
            int[] fib = new int[20];
            int i = 0;
            fib[0] = 1;
            fib[1] = 1;
            for (i = 2; i < fib.length; i++) {
                fib[i] = fib[i - 1] + fib[i - 2];
            }
            return fib;
        }
    

    插值查找

    • 原理:插值查找的主要思路就是划分数组的查找点是自适应,所以该查找的前提是有序数列元素的值是成线性增长的。

    二分查找中查找点计算如下:
      mid=(low+high)/2, 即mid=low+1/2(high-low);
      通过类比,我们可以将查找的点改进为如下:
      mid=low+(key-a[low])/(a[high]-a[low])
    (high-low),
      也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。

    • 加入我们要在[1,100]中找到15,我们设15的下标为m,第一个数的下标(first),第二个数的下标(last),由于数列线性增长,我们不难得到(m-first)/(last-first) ≈ (15-A[first])/(A[last]-A[first])进而得到:m = first + (15-A[first])/(A[last]-A[first])*(last-first).
    public static Comparable InsertionSearch(Comparable[] data, Comparable target, int key, int low, int hight) {
            if (key < low || key > hight || low < hight) {
                throw new NumberFormatException("Wrong number");
            } else {
                int mid;
                Comparable result = null;
                while (result == null && low <= hight) {
                    mid = low + (key - low) / (hight - low) * (hight - low);
                    if (data[mid].compareTo(target) == 0) {
                        result = data[mid];
                    } else if (data[mid].compareTo(target) > 0)
                        hight = mid - 1;
                    else
                        low = mid + 1;
                }
                return result;
            }
        }
    

    实验三-查找与排序-4

    补充实现课上讲过的排序方法:希尔排序,堆排序,桶排序,二叉树排序等
    测试实现的算法(正常,异常,边界)
    提交运行结果截图
    推送相关代码到码云上

    堆排序

    • 利用已经完善的类LinkedMaxHeap,现将要排序的数组的元素加入到堆(最大)中,利用removeMax()方法将元素按照从大到小输出。
    public static void HeapSort(Comparable[] data){
          LinkedMaxHeap myTree = new LinkedMaxHeap();
          for (int i=0;i<data.length;i++){
             myTree.add(data[i]);
          }
          for (int i=0;i<data.length;i++){
             data[i]=myTree.removeMax();
          }
       }
    
  • 相关阅读:
    0.1.3 set的用法
    JoinPoint
    砝码组合(dfs)
    强大的【环绕通知】
    applicationContext.xml 模板
    各种jar包
    装饰博客(二)添加宠物
    装饰博客(一)添加背景图片
    拖拽功能的实现
    点击之后连接qq
  • 原文地址:https://www.cnblogs.com/wbiao21/p/7823311.html
Copyright © 2020-2023  润新知