2.分而治之

   算法设计方法之一——分而治之,模仿了法国皇帝拿破仑在1852年12月2日奥斯特里茨战役中采用的接触策略。
   分而治之(divide-and-conquer)将问题的一个实例划分为两个或更多个较小的实例,一直持续划分实例指导规模小到可以轻松获得答案为止。是一种自顶向下的方法。

1. 二分查找

/**
     * 二分查找
     * 基于非递减的有序数组
     * @param s 非递减数组,查找区域
     * @param x 查找值
     * @return 返回查找值所在位置,如查找不到返回-1
     */
    public int binsearch(int[] s,int x){
        int location =-1;
        int start = 0;
        int end = s.length-1;
        int mid;
        while(location==-1 && start<=end){
            mid = (start+end)/2;
            if(s[mid]==x){
                location =mid;
            }else if(s[mid]< x){
                start = mid+1;
            }else{
                end = mid-1;
            }
        }
        return location;
    }

2. 合并排序

   两路合并(two-way merging),表示将两个有序数组合并为一个有序数组。合并排序即重复应用两路合并完成对数组的排序。
**此代码有错,还未调试成功,希望有大神可以提供意见**
  /**
    * 合并排序
    * 将n个建排列为非递减序列
    * @param S 排序后的有序数组cun'fan'f
    */
    static int S[] = {};
    /**
      * 两路合并
      * 将两个有序数组合并为一个有序数组
      **/
    public void merge(int[] arr1,int[] arr2 ){
        int i=0,j=0,k=S.length;
        Arrays.copyOf(S,k+arr1.length+arr2.length);
        while(i<arr1.length && j<arr2.length){
            if(arr1[i]<arr2[j]){
                S[k]=arr1[i];
                i++;
            }else{
                S[k]=arr2[j];
                j++;
            }
            k++;
        }
        if(i<arr1.length){
            System.arraycopy(S,k,arr1,arr1[i],arr1.length-i);
        }
        if(j<arr1.length){
            System.arraycopy(S,k,arr2,arr2[j],arr2.length-j);
        }
    }
    /**
     * 分而治之方法,拆分要排序的数组
     * 调用merge()方法,两辆排序
     * @param args 要排序的数组
     */

    public void mergesort(int[] arr){
        int len = arr.length;
        int [] left;
        int [] right;
        int devide;
        if(len>1){
            devide = len/2;
            left = new int[devide];
            System.arraycopy(arr,0,left,0,devide);
            right = new int[len-devide];
            System.arraycopy(arr,devide,right,0,right.length);
            mergesort(left);
            mergesort(right);
            merge(left,right);
        }
    }

3. 快速排序

/**
     * 快速排序
     * @param arr 要排序的数组
     * @param start 数组起始下标
     * @param end 数组结束下标
     */
    public void quicksort(int[] arr,int start,int end){
        /**
         * 首先判断该数组长度是否大于1
         */
        if(start<end){
            int i=start;
            int j=end;
            /**
             * 以起始值为基准,并且该位置即为一个坑
             */
            int x=arr[start];
            while(i<j){
                /**
                 * 从倒序分别与基准值x比对,大于基准值则比对下一项
                 */
                while(i<j && arr[j]>=x){
                    j--;
                }
                /**
                 * 直至该项值小于基准值,将该值放入正序的第一个坑,并且此位置空出来成为了一个坑
                 */
                if(i<j){
                    arr[i++]=arr[j];
                }
                /**
                 * 从正序开始分别与基准值比对,小于基准值则比对下一项
                 */
                while(i<j && arr[i]<=x){
                    i++;
                }
                /**
                 * 直至该项值大于基准值,将该值放入刚刚腾出来的坑,并且此位置空处理啊成为了一个坑
                 */
                if(i<j){
                    arr[j--]=arr[i];
                }
            }
            /**
             * 将基准值x放入最后空出来的一个坑
             * 经过上面排序之后,该基准值x左边都是小于该值的项,右边都是大于该值的项
             */
            arr[i]=x;
            quicksort(arr,start,i-1);
            quicksort(arr,i+1,end);
            for(int l=0;l<arr.length;l++){
                System.out.print(arr[l]+"  ");
            }
            System.out.println();
        }
    }

4. Strassen矩阵乘法算法

   1969年,Strassen发表了一种算法,对于矩阵的计算,无论是乘法或者加减法,其时间复杂度都优于根据矩阵的定义去计算。

5. 大整数的算数运算

   大整数,是指超出计算机硬件所能表示的整数范围。如果需要表示这样的大整数,就只能通过软件来表示和处理这些整数。
  • 大整数的加减法及其他线性时间运算
    可以使用一个整数数组来表示大整数,每个位置存储一个数位。例如:534127的存储,存储到数组S中
    S[6]
    S[5] |S[4]| S[3]| S[2]| S[1]| S[0]
    —-|—–|——|—–|—–|—–
    5 |3 |4 |1 |2 |7
    线性运算:
    u10m
    u/10m
    umod10m
    例如: 534127=534103+127
  • 大整数的乘法
    567832=567103+832
    9423723=9423103+723
    按照分而治之的思想,一个n位的大整数u,可以表示为:
    u=x10(n/2)+y
    y(n/2)
    x(nn/2)
    两个整数相乘:
    u=x10m+y
    z=w10m+z
    uz=(x10m+y)(w10m+z)=xw102m+(xz+yw)10m+yz

该代码还待修正

/**
     * 大整数乘法
     * @param u 整数1
     * @param v 整数2
     */
    public int prod(int u,int v){
        int x,y,w,z;
        int n = 6,m;
        if(u==0||v==0){
            return 0;
        }
        else{
            m =n/2;
            int pow = (int)Math.pow(10,m);
            x=u/pow;
            y=u%pow;
            w=v/pow;
            z=v%pow;
            return x*w*(int)Math.pow(10,2*m)+(x*z+y*w)*pow+y*z;
        }
    }

6. 确定阈(yu)值

最优阈值:n
递归需要消耗大量的计算机内存,例如Strassen矩阵算法中,当矩阵为一阶矩阵时,直接按矩阵定义计算乘积反而比调用分而治之发效率高,类似于这样,求最优阈值n,当n大于该阈值时调用某个方法,当n小于阈值时调用另一效率更高的方法,这样可以使运算效率更快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

holyZhang2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值