写出正确的代码是技术,写出优美的代码时艺术。前两天在看排序算法,其中看到归并排序的时候,发现一个编码的技巧。
我先复习一下,归并排序先吧。
分析: 归并排序采用分治的思想。将一个大问题分解若干个子问题,子问题与 原问题,解决的方式是一样的,并且子问题是独立的即子问题之间没有关系,最小的子问题是有解的并且好解。这里是不是很想我们学过的递归。
分治是一种解题思路,递归是一种编码技巧。这里具体时这样实现的,将未排序的数据分为有序的两部分,然后对这两部分进行排序。而对于被分为两部分的数据,再各自当作原问题,按照刚刚的思路,分为两部分有序的数据,直到数据大小唯一的时候。
即:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
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|编码中的小技巧之防止数据溢出】愿我们都能:自身完成确定性增长,面对外界的不确定性,进行“确定增长”。
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)