最大子数组问题分治法(递归)Java实现

FindMaximumSubArray.java
public class   FindMaximumSubArray{
          private int   low   ;
          private int   high   ;
          private int   sum   ;

          public void   FindMaximumSubArray(   int a[], int low, int high) {
                 int mid;//中间位置
                 //左数组
                 int leftLow;
                 int leftHigh;
                 int leftSum;
                 //右数组
                 int rightLow;
                 int rightHigh;
                 int rightSum;
                 //中间数组
                 int crossLow;
                 int crossHigh;
                 int crossSum;
                 if (high == low) {//只有一个元素
                        this .high   = low;
                        this .low   = low;
                        this .sum   =a[low];
              else {//至少两个元素
                     mid= (   int )((low + high) / 2);//向下取整
                     FindMaximumSubArraycalLeft = new FindMaximumSubArray();//搜索左边
                     calLeft.FindMaximumSubArray(a,low, mid);
                     leftLow= calLeft.getLow();
                     System.   out .println("FindMaximumSubArray.leftLow="   +leftLow);
                     leftHigh= calLeft.getHigh();
                     System.   out .println("FindMaximumSubArray.leftHgih="   +leftHigh);
                     leftSum= calLeft.getSum();
                     System.   out .println("FindMaximumSubArray.leftLSum="   +leftSum);
                     FindMaximumSubArraycalRight = new FindMaximumSubArray();//搜索右边
                     calRight.FindMaximumSubArray(a,mid + 1, high);
                     rightLow= calRight.getLow();
                     System.   out .println("FindMaximumSubArray.rightLow="   +rightLow);
                     rightHigh= calRight.getHigh();
                     System.   out .println("FindMaximumSubArray.rightHgih="   +rightHigh);
                     rightSum= calRight.getSum();
                     System.   out .println("FindMaximumSubArray.rightSum="   +rightSum);
                     FindMaxCrossingSubArraycalCross = new FindMaxCrossingSubArray();//搜索从中间开始
                     calCross.FindMaxCrossingSubArray(a,low, mid, high);
                     crossLow= calCross.getMaxLeft();
                     System.   out .println("FindMaxCrossingSubArray.crossLow="   +crossLow);
                     crossHigh= calCross.getMaxRight();
                     System.   out .println("FindMaxCrossingSubArray.crossHigh="   +crossHigh);
                     crossSum= calCross.getSum();
                     System.   out .println("FindMaxCrossingSubArray.crossSum="   +crossSum);
                        if ((leftSum >= rightSum) && (leftSum>crossSum)) { //在有零元素的情况下,包含零元素的才是最大子数组,Cross中包含
                              this .low   =leftLow;
                              this .high   =leftHigh;
                              this .sum   =leftSum;
                     else if   ((rightSum>= leftSum) && (rightSum >crossSum)){//在有零元素的情况下,包含零元素的才是最大子数组,Cross中包含
                              this .low   =rightLow;
                              this .high   =rightHigh;
                              this .sum   =rightSum;
                     else {
                              this .low   =crossLow;
                              this .high   =crossHigh;
                              this .sum   =crossSum;
                     }
              }
       }

         
          public int   getLow(){
                 return low   ;
       }

         
          public int   getHigh(){
                 return high   ;
       }

         
          public int   getSum(){
                 return sum   ;
       }

}

FindMaxCrossingSubArray.java
public class   FindMaxCrossingSubArray {
          private int   sum   =0;
          private int   sumLeft   =0;
          private int   sumRight   =0;
          private int   maxLeft   ;
          private int   maxRight   ;
       
          public void   FindMaxCrossingSubArray(   int a[], int low, int mid,   int high){
                 if (low == high){//子数组元素个数为一
                        //sumLeft=a[low];
                        //sumRight=a[low];
                        sum=a[low];
                        maxLeft=low;
                        maxRight=low;
              }   else {//子数组元素个数卜为一
                        sumLeft=a[mid];
                        sumRight=a[mid+1];
                        maxLeft=mid;
                        maxRight=mid+1;
                        for (int   i=mid;i>=0;i--){
                              sum+=a[i];
                              if (sum   >sumLeft   ){
                                     sumLeft=   sum;
                                     maxLeft=i;
                           }
                     }
                        sum=0;
                        for (int   i=mid+1;i<=high;i++){
                              sum+=a[i];
                              if (sum   >sumRight   ){
                                     sumRight=   sum;
                                     maxRight=i;
                           }
                     }
                        sum=   sumLeft+   sumRight;
              }
              
       }
         
          public int   getSum(){
                 return sum   ;
       }
         
          public int   getSumLeft(){
                 return sumLeft   ;
       }
         
          public int   getSumRight(){
                 return sumRight   ;
       }
         
          public int   getMaxLeft(){
                 return maxLeft   ;
       }
         
          public int   getMaxRight(){
                 return maxRight   ;
       }
}

testFindMaxCrossingSubArray.java

import java.util.Random;

public class   testFindMaxCrossingSubArray {
          int a   [];
         
          public int   [] getA(){
                 return a   ;
       }

          int low   ;
          int high   ;
          int mid   ;
          int sum   ;
          int length   =2;
       Random random=   new Random();
         
          private void   initTest1(){
                 a=   new int   [length   ];
                 for (int   i=0;i<</SPAN> length;i++){
                        a[i]=   random.nextInt(40)-20;
              }
                 low=0;
                 high=   length-1;
                 sum=0;
                 mid=(   int )((low   +high   )/2);
       }
         
          private void   cal(){
              FindMaxCrossingSubArraycal=   new FindMaxCrossingSubArray();
              cal.FindMaxCrossingSubArray(   alowmidhigh);
                 sum=cal.getSum();
                 low=cal.getMaxLeft();
                 high=cal.getMaxRight();
       }
         
          private void   calPrint(){
              System.   out .print("a=["   );
                 for (int   i=0;i<</SPAN> length;i++){
                     System.   out .print(a   [i]+""   );
              }
              System.   out .println("]"   );
              System.   out .print("a["   +(low   +1)+"..."   +high   +"]=["   );
                 for (int   i=low   ;i<=high   ;i++){
                     System.   out .print(a   [i]+""   );
              }
              System.   out .println("]"   );
              System.   out .println("sum="   +sum   );
       }
       
          public void   test(){
              initTest1();
              cal();
              calPrint();
       }
}

testFindMaximumSubArray.java

import java.util.Random;

public class   testFindMaximumSubArray {
          int length   ;//getter &setter
          int a   []= new int[ length]; //setter
          int low   ;
          int high   ;
          int mid   ;
          int sum   ;
       
          //a=new int [length];
       
       Random random=   new Random();
         
          private void   initTest1(){
              
                
                 low=0;
                 high=   length-1;
                 sum=0;
                 //mid=(int )((low+high)/2);
       }
         
          private void   cal(){
              FindMaximumSubArraycal=   new FindMaximumSubArray();
              cal.FindMaximumSubArray(   alowhigh);
                 sum=cal.getSum();
                 low=cal.getLow();
                 high=cal.getHigh();
       }
         
          private void   calPrint(){
                 //输出数组
              System.   out .print("a=["   );
                 for (int   i=0;i<</SPAN> length;i++){
                     System.   out .print(a   [i]+""   );
              }
              System.   out .println("]"   );
                 //输出最大子数组
              System.   out .print("a["   +(low   +1)+"..."   +(high   +1)+"]=["   );
                 for (int   i=low   ;i<=high   ;i++){
                     System.   out .print(a   [i]+""   );
              }
              System.   out .println("]"   );
              System.   out .println("sum="   +sum   );
       }
       
          public void   test(){
              initTest1();
              cal();
              calPrint();
       }
       
         
          public int   getLength(){
                 return length   ;
       }
         
          public void   setLength( int length){
                 this .length   =length;
       }
         
          public void   setA( int[]a) {
                 this .a   =a;
       }
}

main.java

import java.util.Random;


public class   main{

          static Random random   = new Random();

          public static   void main(String[]args) {
                 // TODO 自动生成的方法存根
                 //testFindMaxCrossingSubArray testC=newtestFindMaxCrossingSubArray ();
                 //testC.test();
                 int length=20;//测试的数组长度
              testFindMaximumSubArraytestM=   new testFindMaximumSubArray();
              testM.setLength(length);
                 int a[]=new   int[length];
                 for (int   i=0;i
              a[i]=   random .nextInt(40)-20;
              }
              testM.setA(a);
              testM.test();
       }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值