归并排序(非递归,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实现非递归--归并排序
另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并 ...
随机推荐
- Java线程和守护进程
ava的线程机制,有两类线程:User Thread(用户线程).Daemon Thread(守护线程) . 操作系统里面是没有守护线程的概念,只有守护进程,但是Java语言机制是构建在JVM的基础之 ...
- 【java学习笔记】线程
1.线程的定义 ①继承Thread类,将执行的任务逻辑放到run方法中,调用start方法来开启线程 public class ThreadDemo { public static void main ...
- 【转载】Ubuntu环境下安装QT(转)
Ubuntu 安装 Qt 开发环境 简单实现是本文要介绍的内容,内容很短,取其精华,详细介绍Qt 类库的说明,先来看内容. 一.Ubuntu下安装Qt $ sudo apt-get install q ...
- php中的单引号、双引号和转义字符
PHP单引号及双引号均可以修饰字符串类型的数据,如果修饰的字符串中含有变量(例$name):最大的区别是: 双引号会替换变量的值,而单引号会把它当做字符串输出. 例如: <?php ...
- 详解Linux Initrd
在Linux操作系统中,有一项特殊的功能--初始化内存盘INITRD(INITial Ram Disk)技术,而且内核支持压缩的文件系统映像.有了这两项功能,我们可以让Linux系统从小的初始化内存盘 ...
- Ubuntu 上 hi3531 交叉编译环境 arm-hisiv100nptl-linux 搭建过程
安装SDK 1.Hi3531 SDK包位置 在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx ...
- StackExchange.Redis 二次封装
在NuGet直接搜索StackExchange.Redis,下载引用包: 帮助类: public class RedisUtils { /// <summary> /// redis配置文 ...
- 畅通工程再续 HDU - 1875
相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政 ...
- 省市区/国籍 多级联动-jq
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Ubuntu出现ERR_PROXY_CONNECTION_FAILED错误解决方案
我是Ubuntu新手,因为想查看国外的资料,然后安装了灯笼,结果打开谷歌浏览器出现了ERR_PROXY_CONNECTION_FAILED错误,未连接到互联网,代理服务器出现错误,然后Firefox也 ...