public static void main(String[] args) {
// 定义无序数组
Integer[] arr = new Integer[]{12,14,56,89,11,66,99,3,6,34};
// 插入排序前
System.out.println("插入排序前");
Arrays.asList(arr).forEach(e -> System.out.print(e + " "));
System.out.println("\r\n"+"插入排序后");
// 插入排序后:
Arrays.asList(insertionSort(arr)).forEach(e -> System.out.print(e + " "));
// 定义无序数组
Integer[] arg = new Integer[]{12,14,56,89,11,66,99,3,6,34};
// 归并排序前
System.out.println("\r\n"+ "归并排序前");
Arrays.asList(arg).forEach(e -> System.out.print(e + " "));
// 归并排序后
System.out.println("\r\n"+"归并排序后");
Arrays.asList(mergeSort(arg)).forEach(e-> System.out.print(e + " "));
}
/**
* 插入排序 时间复杂度O(n^2)
* 思路 (1)当前元素的前面元素均为有序
* (2)要插入时,从当前元素的左边开始往前找(从后往前找),比当前元素大的元素均往右移一个位置
* @param arr
* @return
*/
private static Integer[] insertionSort(Integer[] arr){
long start = new Date().getTime();
for (int i = 1; i < arr.length; i++) {
if (arr[i-1] > arr[i]) { // 如果 i比前一位小 进行插入操作
int temp = arr[i]; // 记录arr[i]的值
int j = i; // 记录下角标
while (j > 0 && temp < arr[j-1]) {
arr[j] = arr[j-1]; // 前一位数向后挪一位
j--;
}
arr[j] = temp;
}
}
long end = new Date().getTime();
System.out.println("插入排序运行时间 :" + (end - start) + " 毫秒");
return arr;
}
/**
* 归并排序 时间复杂度 O(n log n)
* 思路 Divide: 把长度为n的输入序列分成两个长度为n/2的子序列。
* Conquer: 对这两个子序列分别采用归并排序。
* Combine: 将两个排序好的子序列合并成一个最终的排序序列
* @param arg
* @return
*/
private static Integer[] mergeSort(Integer[] arg){
long start = new Date().getTime();
Integer[] temp = new Integer[arg.length];
sort(arg, 0, arg.length);
long end = new Date().getTime();
System.out.println("程序运行时间 :" + (end - start) + " 毫秒");
return arg;
}
/**
* "归" 递归拆分数组
*
* @param numbers
* @param pos
* @param end
*/
public static void sort(Integer[] numbers,Integer pos,Integer end){
if ((end - pos) > 1) { // 递归出口 当数组不可再分时 跳出递归
int offset = (end + pos) >> 1; // 分成2个数组
sort(numbers, pos, offset); // 分别取前半部分和后半部分数组进行递归排序
sort(numbers, offset, end); // 向下递归直到找到叶子节点
merge(numbers, pos, offset, end); // 合并俩个排好序的数组
}
}
/**
* "并" 将排好序的数组合并
*
* @param numbers
* @param pos
* @param offset
* @param end
*/
public static void merge(Integer[] numbers,Integer pos,Integer offset,Integer end){
Integer[] array1 = new Integer[offset - pos]; // array1 为numbers数组前半部分
Integer[] array2 = new Integer[end - offset]; // array2 为后半部分
System.arraycopy(numbers, pos, array1, 0, array1.length); // 从数组源numbers复制数组到 array1
System.arraycopy(numbers, offset, array2, 0, array2.length); // 从数组源numbers复制数组到 array2
for (int i = pos, j = 0, k = 0; i < end ; i++) {
if (j == array1.length) { // 俩个数组有一个数组元素耗尽(都比较过排好序后)时
System.arraycopy(array2, k, numbers, i, array2.length - k); // 将另一个数组复制到numbers数组中
break;
}
if (k == array2.length) {
System.arraycopy(array1, j, numbers, i, array1.length - j);
break;
}
if (array1[j] <= array2[k]) { // 后半部分数组元素跟前半部分比较
numbers[i] = array1[j++]; // 如果前半部分元素小于或等于后半部分元素 numbers数组元素位置不变
} else { // j++ 继续判断 前半部分后一位元素 跟后半部分比较
numbers[i] = array2[k++]; // 否则 numbers数组元素 i位元素替换为 后半部分元素
} // k++ 继续判断 后半部分后一位元素 跟前半部分比较
}
}
插入排序及归并排序java代码实现及详细注释
猜你喜欢
转载自blog.csdn.net/name_javahadoop/article/details/77776904
今日推荐
周排行