归并排序(非递归,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实现非递归--归并排序
另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并 ...
随机推荐
- JavaScript网页全屏API
在大多数的浏览器中都有实现网页全屏显示的功能,并且大部分浏览器实现全屏显示和退出全屏显示的快捷键通常是F11和Esc两个按键.如今,W3C已经制定了关于网页全屏显示的API,利用这个API 可以实现网 ...
- MySQL双主一致性架构优化
一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能,保证读库的高可用,但此时写库仍然是单点. 在一个MySQL数据库集群中可以设置两个主库,并设置双向 ...
- Storm实践
1.Storm命令 在Linux中观直接输入Storm,不带任何参数信息,可以查看Storm命令. 参考这里 1. activate 激活指定的拓扑Spout.语法:storm activate t ...
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- GAN︱生成模型学习笔记(运行机制、NLP结合难点、应用案例、相关Paper)
我对GAN"生成对抗网络"(Generative Adversarial Networks)的看法: 前几天在公开课听了新加坡国立大学[机器学习与视觉实验室]负责人冯佳时博士在[硬 ...
- zTree实现地市县三级级联数据库映射
zTree实现地市县三级级联数据库映射 Province.hbm.xml: <?xml version="1.0" encoding="UTF-8"?&g ...
- freemarker.core.InvalidReferenceException
1.错误描述 freemarker.core.InvalidReferenceException:on line 68,column 18 in ftl/inc/incPro.ftl p.mainSe ...
- TypeError: Error #1006: value 不是函数。
1.错误原因 TypeError: Error #1006: value 不是函数. at BasicChart/dataFunc()[E:\Flash Builder\Map\src\BasicCh ...
- 芝麻HTTP:Scrapy-Splash的安装
Scrapy-Splash是一个Scrapy中支持JavaScript渲染的工具,本节来介绍它的安装方式. Scrapy-Splash的安装分为两部分.一个是Splash服务的安装,具体是通过Dock ...
- Struts2的数据封装
在很多的实际开发场景中,页面提交请求参数Action ,在Action中接收参数并对接收的数据进行封装.封装到一个JavaBean中,将JavaBean传递给业务层中.Struts2数据封装分为两类: ...