编码中的小技巧之防止数据溢出

写出正确的代码是技术,写出优美的代码时艺术。

前两天在看排序算法,其中看到归并排序的时候,发现一个编码的技巧。
我先复习一下,归并排序先吧。
分析: 归并排序采用分治的思想。将一个大问题分解若干个子问题,子问题与 原问题,解决的方式是一样的,并且子问题是独立的即子问题之间没有关系,最小的子问题是有解的并且好解。这里是不是很想我们学过的递归。

分治是一种解题思路,递归是一种编码技巧。

这里具体时这样实现的,将未排序的数据分为有序的两部分,然后对这两部分进行排序。而对于被分为两部分的数据,再各自当作原问题,按照刚刚的思路,分为两部分有序的数据,直到数据大小唯一的时候。

即:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

Take is cheap .Show me the code .

代码

import java.util.Arrays;

public class MergeSort {

   public static void main(String[] args) {
       int n = 100;
       int [] a = new int[n];

       for(int i = 0;i= r)
           return ;
       //防止 (r+p)溢出
       int q = p + (r - p)/2;

       mergeSort(A,p,q);
       mergeSort(A,q+1,r);

       merge(A,p,q,r);


   }

   private static void merge(int[] A, int p, int q, int r) {
       int i = p;
       int j = q+1;

       int []temp = new int[r-p+1];
       int index = 0;
       while(i <=q && j <=r){
           // 需要 <= 等于号保证 稳定性
           if(A[i] <= A[j]){
               temp[index++] = A[i];
               i++;
           }else{
               temp[index++] = A[j];
               j++;
           }
       }

       //判断那边有剩余 只有一边有剩余 或者 都没有, 先假定是 第一部分 有剩余
       int start = i;
       int end = q;

       // 看是不是 第二部分 有剩余
       if(j <= r){
           start = j;
           end = r;
       }



       //剩余部分拷贝
       while(start <= end){
           temp[index++]  = A[start++];
       }

       //将临时的数组拷贝到 A的(p,r)中
       for( i = 0;i

代码其中有一部分

// 取p到r之间的中间位置q,防止(p+r)的和超过int类型最大值
int q = p + (r - p)/2;

看到时候我发现以前自己没有想到过这种问题。
是不是不像平时写的那样 int q = (r+p)/2; 没有考虑到给你的数据大小时合适的,但操作的时候,不自觉的放大了,可能会发生某种问题。

愿我们都能:自身完成确定性增长,面对外界的不确定性,进行“确定增长”。

你可能感兴趣的:(Java,排序)