分治法实现求解最大子数组

 

  
  
  
  
  1. package com.C2;  
  2.  
  3. public class MaxSubArray {  
  4.     /**  
  5.      * 该方法是整个算法的核心,就是最基本的处理单元 Nuclear Processing Unit (NPU)  
  6.      * @param subArray 该方法接受一个 数组、下表low、high和middle 数据结构的实例  
  7.      * @return a instance of ResultArray 返回一个下标元组,该元组指定了跨越中点的最大子数组的边界以及  
  8.      *  这个最大子数组的和(此三者组成一个数据结构)  
  9.      */  
  10.     public static ResultArray find_max_crossing_subarray(SubArray subArray) {  
  11.         int[] array = subArray.getArray();  
  12.         //先从中间坐标向左进行遍历,顺序不能颠倒  
  13.         int left_sum = Integer.MIN_VALUE;  
  14.         int low = subArray.getMiddle();//这个low是来确定返回的最大子数组的左边边界坐标  
  15.         int sum = 0;  
  16.         for (int i = low; i >= subArray.getLow(); i--) {  
  17.             sum += array[i];  
  18.             if (sum > left_sum) {//一旦当前的和变得更大,则取代当前的和并且重置low的值  
  19.                 left_sum = sum;  
  20.                 low = i;  
  21.             }  
  22.         }  
  23.         //再从中间坐标向左进行遍历  
  24.         int right_sum = Integer.MIN_VALUE;  
  25.         int high = subArray.getMiddle() + 1;//这个low是来确定返回的最大子数组的右边边界坐标  
  26.         sum = 0;  
  27.         for (int i = high; i <= subArray.getHigh(); i++) {  
  28.             sum += array[i];  
  29.             if (sum > right_sum) {//一旦当前的和变得更大,则取代当前的和并且重置high的值  
  30.                 right_sum = sum;  
  31.                 high = i;  
  32.             }  
  33.         }  
  34.         //返回最大子数组的下标以及和  
  35.         return new ResultArray(low, high, left_sum + right_sum);  
  36.     }  
  37.       
  38.     /**  
  39.      * 该方法是整个算法的调度中心,是出口和入口 Nuclear Scheduling Unit (NSU)  
  40.      * @param tempArray 请记住,TempArray定义了问题的形式,它因此成为递归的接受者和被处理的中间数据结构  
  41.      * @return a instance of ResultArray  
  42.      */  
  43.     public static ResultArray find_max_subarray(TempArray tempArray) {  
  44.         if (tempArray.getLow() == tempArray.getHigh())  
  45.             //如果当前问题是左右下标一样大,则直接返回,这是问题的基本情况,递归的出口,要首先判断  
  46.             return new ResultArray(tempArray.getLow(), tempArray.getHigh(), tempArray.getArray()[tempArray.getLow()]);  
  47.         else {  
  48.             int middle = (tempArray.getLow() + tempArray.getHigh()) / 2; //计算中间坐标,取  
  49.             ResultArray leftResultArray = find_max_subarray(new TempArray(  
  50.                     tempArray.getLow(), middle, tempArray.getArray())); //左边递归  
  51.             ResultArray rightResultArray = find_max_subarray(new TempArray(  
  52.                     middle + 1, tempArray.getHigh(), tempArray.getArray()));    //右边递归  
  53.             ResultArray crossingResultArray = find_max_crossing_subarray(new SubArray(  
  54.                     tempArray.getLow(), tempArray.getHigh(), middle, tempArray.getArray()));    //跨界的最大数组  
  55.             if (leftResultArray.getSum() >= rightResultArray.getSum()  
  56.                     && leftResultArray.getSum() >= crossingResultArray.getSum())  
  57.                 return leftResultArray;  
  58.             else if (rightResultArray.getSum() >= leftResultArray.getSum()  
  59.                     && rightResultArray.getSum() >= crossingResultArray.getSum())  
  60.                 return rightResultArray;  
  61.             else  
  62.                 return crossingResultArray;  
  63.         }  
  64.     }  
  65.     /**  
  66.      * 次数据结构归纳了要处理的问题的形式,该形式作为NSU的入口,也就是递归的形式 Original Question Form (OQF)  
  67.      * @author xingzhe  
  68.      */  
  69.     static class TempArray {  
  70.         int low;  
  71.         int high;  
  72.         int[] array;  
  73.  
  74.         public TempArray() {  
  75.         }  
  76.  
  77.         public TempArray(int low, int high, int[] a) {  
  78.             this.setLow(low);  
  79.             this.setHigh(high);  
  80.             this.setArray(a);  
  81.  
  82.         }  
  83.  
  84.         public int getLow() {  
  85.             return low;  
  86.         }  
  87.  
  88.         public void setLow(int low) {  
  89.             this.low = low;  
  90.         }  
  91.  
  92.         public int getHigh() {  
  93.             return high;  
  94.         }  
  95.  
  96.         public void setHigh(int high) {  
  97.             this.high = high;  
  98.         }  
  99.  
  100.         public int[] getArray() {  
  101.             return array;  
  102.         }  
  103.  
  104.         public void setArray(int[] array) {  
  105.             this.array = array;  
  106.         }  
  107.  
  108.     }  
  109.     /**  
  110.      * 该数据结构是问题的最终形式,就是用户要得到的数据机构 Result Form (RF)  
  111.      * @author xingzhe  
  112.      */  
  113.     static class ResultArray {  
  114.         int low;  
  115.         int high;  
  116.         int sum;  
  117.  
  118.         public ResultArray(int low, int high, int sum) {  
  119.             this.setLow(low);  
  120.             this.setHigh(high);  
  121.             this.setSum(sum);  
  122.         }  
  123.  
  124.         public ResultArray() {  
  125.  
  126.         }  
  127.  
  128.         public int getLow() {  
  129.             return low;  
  130.         }  
  131.  
  132.         public void setLow(int low) {  
  133.             this.low = low;  
  134.         }  
  135.  
  136.         public int getHigh() {  
  137.             return high;  
  138.         }  
  139.  
  140.         public void setHigh(int high) {  
  141.             this.high = high;  
  142.         }  
  143.  
  144.         public int getSum() {  
  145.             return sum;  
  146.         }  
  147.  
  148.         public void setSum(int sum) {  
  149.             this.sum = sum;  
  150.         }  
  151.  
  152.         @Override  
  153.         public String toString() {  
  154.             return "ResultArray [low=" + low + "high=" + high + "sum="  
  155.                     + sum + "]";  
  156.         }  
  157.  
  158.     }  
  159.     /**  
  160.      * 该数据结构是NPU的处理形式,NPU处理之后返回的一定是问题的最终形式  Processing Form(PF)  
  161.      * @author xingzhe  
  162.      */  
  163.     static class SubArray {  
  164.         int low;  
  165.         int high;  
  166.         int middle;  
  167.         int[] array;  
  168.  
  169.         public SubArray(int i, int j, int k, int[] a) {  
  170.             this.setLow(i);  
  171.             this.setHigh(j);  
  172.             this.setMiddle(k);  
  173.             this.setArray(a);  
  174.         }  
  175.  
  176.         public int getLow() {  
  177.             return low;  
  178.         }  
  179.  
  180.         public void setLow(int low) {  
  181.             this.low = low;  
  182.         }  
  183.  
  184.         public int getHigh() {  
  185.             return high;  
  186.         }  
  187.  
  188.         public void setHigh(int high) {  
  189.             this.high = high;  
  190.         }  
  191.  
  192.         public int getMiddle() {  
  193.             return middle;  
  194.         }  
  195.  
  196.         public void setMiddle(int middle) {  
  197.             this.middle = middle;  
  198.         }  
  199.  
  200.         public int[] getArray() {  
  201.             return array;  
  202.         }  
  203.  
  204.         public void setArray(int[] array) {  
  205.             this.array = array;  
  206.         }  
  207.  
  208.     }  
  209.  
  210.     public static void main(String[] args) {  
  211.         int length = 20000000;  
  212.         int[] array = new int[length];  
  213.         int max = 500;  
  214.         int min = -500;  
  215.         for (int i = 0; i < length; i++) {  
  216.             array[i] = (int) Math.round(Math.random() * (max - min) + min);//获取max和min之间的整数  
  217.         }  
  218.         TempArray t = new TempArray();  
  219.         t.setArray(array);  
  220.         t.setLow(0);  
  221.         t.setHigh(length - 1);  
  222.         System.out.println("\r\n"+find_max_subarray(t));  
  223.     }  
  224. }  

 

你可能感兴趣的:(最大子数组)