归并排序(非递归,Java实现)
归并排序(非递归):自底向上
public class MergeSort {
/**
* @param arr 待排序的数组
* @param left 本次归并的左边界
* @param mid 本次归并的中间位置,也就是分界线
* @param right 本次归并的右边界
* @param <T> 泛型
* @local aux 辅助空间(Auxiliary Space)
*/
private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);
int i = left;
int j = mid + 1;
for (int t = left; t <= right; t++) {
if (i > mid) {
arr[t] = aux[j++ - left];
} else if (j > right) {
arr[t] = aux[i++ - left];
} else if (aux[i - left].compareTo(aux[j - left]) < 0) {
arr[t] = aux[i++ - left];
} else {
arr[t] = aux[j++ - left];
}
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
int n = arr.length;
for (int size = 1; size < n; size *= 2) {
for (int i = 0; i < n - size; i += size * 2) {
merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
}
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr) {
sort(arr, 0, arr.length - 1);
}
private static void printArr(Object[] arr) {
for (Object o : arr) {
System.out.print(o);
System.out.print("\t");
}
System.out.println();
}
public static void main(String args[]) {
Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
printArr(arr);//3 5 1 7 2 9 8 0 4 6
sort(arr);
printArr(arr);//0 1 2 3 4 5 6 7 8 9
}
}
归并排序(非递归)优化:merge前判断是否有必要进行归并
public class MergeSort {
/**
* @param arr 待排序的数组
* @param left 本次归并的左边界
* @param mid 本次归并的中间位置,也就是分界线
* @param right 本次归并的右边界
* @param <T> 泛型
* @local aux 辅助空间(Auxiliary Space)
*/
private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);
int i = left;
int j = mid + 1;
for (int t = left; t <= right; t++) {
if (i > mid) {
arr[t] = aux[j++ - left];
} else if (j > right) {
arr[t] = aux[i++ - left];
} else if (aux[i - left].compareTo(aux[j - left]) < 0) {
arr[t] = aux[i++ - left];
} else {
arr[t] = aux[j++ - left];
}
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
int n = arr.length;
for (int size = 1; size < n; size *= 2) {
for (int i = 0; i < n - size; i += size * 2) {
if (arr[i + size - 1].compareTo(arr[i + size]) > 0) {
merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
}
}
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr) {
sort(arr, 0, arr.length - 1);
}
private static void printArr(Object[] arr) {
for (Object o : arr) {
System.out.print(o);
System.out.print("\t");
}
System.out.println();
}
public static void main(String args[]) {
Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
printArr(arr);//3 5 1 7 2 9 8 0 4 6
sort(arr);
printArr(arr);//0 1 2 3 4 5 6 7 8 9
}
}
递归排序(非递归)继续优化:对小规模数据使用插入排序
归并排序是对一组一组的数据进行归并。当这一组中的数很少时(暂定为4),使用插入排序。
public class MergeSort {
/**
* @param arr 待排序的数组
* @param left 本次归并的左边界
* @param mid 本次归并的中间位置,也就是分界线
* @param right 本次归并的右边界
* @param <T> 泛型
* @local aux 辅助空间(Auxiliary Space)
*/
private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);
int i = left;
int j = mid + 1;
for (int t = left; t <= right; t++) {
if (i > mid) {
arr[t] = aux[j++ - left];
} else if (j > right) {
arr[t] = aux[i++ - left];
} else if (aux[i - left].compareTo(aux[j - left]) < 0) {
arr[t] = aux[i++ - left];
} else {
arr[t] = aux[j++ - left];
}
}
}
private static <T extends Comparable<? super T>> void insertionSort(T[] arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
T temp = arr[i];
int j = i - 1;
while (j >= left && temp.compareTo(arr[j]) < 0) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
int len = arr.length;
int smallSize = 4;//当规模小于4时采用插入排序
for (int i = 0; i < len; i += smallSize) {
insertionSort(arr, i, Math.min(i + smallSize - 1, len - 1));
}
for (int size = smallSize; size < len; size *= 2) {
for (int i = 0; i < len - size; i += size * 2) {
if (arr[i + size - 1].compareTo(arr[i + size]) > 0){
merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, len - 1));
}
}
}
}
public static <T extends Comparable<? super T>> void sort(T[] arr) {
sort(arr, 0, arr.length - 1);
}
private static void printArr(Object[] arr) {
for (Object o : arr) {
System.out.print(o);
System.out.print("\t");
}
System.out.println();
}
public static void main(String args[]) {
Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
printArr(arr);//3 5 1 7 2 9 8 0 4 6
sort(arr);
printArr(arr);//0 1 2 3 4 5 6 7 8 9
}
}
归并排序(非递归,Java实现)的更多相关文章
- 字符串逆转(递归和非递归java)
package 乒乒乓乓; public class 递归逆转字符串 { //非递归逆转 public static String reverse(String s) { ...
- 二分查找(非递归JAVA)
庞果网编程英雄会上做的一道题:二分查找(非递归),和大家分享一下: public class BinarySearchClass { public static int binary_search(i ...
- 数据结构--汉诺塔--借助栈实现非递归---Java
/*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...
- 【Java】 归并排序的非递归实现
归并排序可以采用递归方法(见:归并排序),但递归方法会消耗深度位O(longn)的栈空间,使用归并排序时,应该尽量使用非递归方法.本文实现了java版的非递归归并排序. 更多:数据结构与算法合集 思路 ...
- Java归并排序的递归与非递归实现
该命题已有无数解释,备份修改后的代码 平均时间复杂度: O(NLogN) 以2为底 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + ...
- 排序算法练习--JAVA(插入、直接选择、冒泡、快速排序、非递归快速排序)
排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... package sort; impor ...
- 面试之路(16)-归并排序详解(MergeSort)递归和非递归实现
归并排序的概念及定义 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立 ...
- 算法笔记_013:汉诺塔问题(Java递归法和非递归法)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...
- javascript实现非递归--归并排序
另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并 ...
随机推荐
- 在测试crontab执行脚本的时候,修改了linux的系统时间,crontab不执行了。
今天在写服务器的perl脚本的时候,在完成一版脚本打算通过crontab来测试一下呢,因为直接执行脚本文件是没有问题的,但是当配置到crontab定期执行时就会出现问题,到了指定的时间了,但是脚本文件 ...
- Selenium里可以自行封装与get_attribute对应的set_attribute方法
我们在做UI自动化测试的过程中,某些情况会遇到,需要操作WebElement属性的情况. 假设现在我们需要获取一个元素的title属性,我们可以先找到这个元素,然后利用get_attribute方法获 ...
- keepalived双机热备nginx
nginx目前是我最常用的反向代理服务,线上环境为了能更好的应对突发情况,一般会使用keepalived双机热备nginx或者使用docker跑nginx集群,keepalived是比较传统的方式,虽 ...
- myeclipse8.5打包jar并引入第三方jar包
用myeclipse自带的export工具,无法引入被引用的第三方的jar包,有两种方式: (1)直接export出jar包,解压jar包(第三方的jar包太多,太麻烦) 在创建好的JAR文件里找到M ...
- 用Node.JS+MongoDB搭建个人博客(model目录)(三)
model目录主要是封装一些经常使用的方法,便于使用. setting.js文件: 很简单,就单单封装了一个url作为公用,以后改就方便改了. md5.js(不推荐用): db.js文件: db.js ...
- probabilistic robotics_Kalman filter(一)
码农生活告一段落,继续.... 多元正态分布 协方差矩阵,为正定对称矩阵.det表示行列式 协方差反应随机样本变量各分量之间的相关性. 当变量的假设模型不一致时,不适合用高斯滤波. 叠加高斯噪声的线性 ...
- 关于我上传的activiti自定义流程demo的说明
最近又收到了一些询问activiti的问题,其中好几个都是向我索要我上传的这个activiti自定义流程demo的数据库设计. 索要的多了,而我早就把这个库给删掉了,所以我便觉得有必要做一个说明: 我 ...
- ubuntu下串口编程备忘
弄了一下串口,一个小问题多折腾了下,备忘.软件环境:zl@zhanglong:~$ cat /etc/lsb-release DISTRIB_ID=UbuntuDISTRIB_RELEASE=12.0 ...
- CentOS配置日志集中管理
①首先有产生日志的服务器和储存日志的服务器 ②产生.接收日志的服务器都必须安装rsyslog服务(可以通过yum.rpm.源码包安装),rsyslog支持C/S模式 ③日志存储服务器需要编辑rsysl ...
- 获取MySql每一列的数据类型和长度默认值等信息
如何获取MySql表中各个列的数据类型? show columns from tablename 返回结果如下: id int(11) NO PRI auto_incr ...