归并排序(非递归):自底向上

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实现)的更多相关文章

  1. 字符串逆转(递归和非递归java)

    package 乒乒乓乓; public class 递归逆转字符串 {    //非递归逆转    public static String reverse(String s)    {       ...

  2. 二分查找(非递归JAVA)

    庞果网编程英雄会上做的一道题:二分查找(非递归),和大家分享一下: public class BinarySearchClass { public static int binary_search(i ...

  3. 数据结构--汉诺塔--借助栈实现非递归---Java

    /*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...

  4. 【Java】 归并排序的非递归实现

    归并排序可以采用递归方法(见:归并排序),但递归方法会消耗深度位O(longn)的栈空间,使用归并排序时,应该尽量使用非递归方法.本文实现了java版的非递归归并排序. 更多:数据结构与算法合集 思路 ...

  5. Java归并排序的递归与非递归实现

    该命题已有无数解释,备份修改后的代码 平均时间复杂度: O(NLogN)  以2为底 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + ...

  6. 排序算法练习--JAVA(插入、直接选择、冒泡、快速排序、非递归快速排序)

    排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... package sort; impor ...

  7. 面试之路(16)-归并排序详解(MergeSort)递归和非递归实现

    归并排序的概念及定义 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立 ...

  8. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

  9. javascript实现非递归--归并排序

    另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并 ...

随机推荐

  1. Spring cloud oauth2.0 access_token 永不失效设置方法

    在AuthorizationServerConfigurerAdapter,重写一个TokenServices,注意这里的@Primary 非常重要,否则会有3个同类型的Bean,无法注入,会抛出以下 ...

  2. 接口测试执行工具Postman:模拟请求、用例执行、断言、批量运行用例、简单持续集成

    一.接口测试-postman-模拟HTTP Requests 二.接口测试-postman-权限Authorization 三.接口测试-postman-断言Writting Test 四.接口测试- ...

  3. java 集合框架(十五)Deque

    一.概述 Deque是Queue的子接口,我们知道Queue是一种队列形式,而Deque则是双向队列,它支持从两个端点方向检索和插入元素,因此Deque既可以支持LIFO形式也可以支持LIFO形式.D ...

  4. Linux 系统裁剪笔记1

    1.什么裁剪? 本篇文章的主要目的是让笔者和读者更深的认识Linux系统的运作方式,大致内容就是把Linux拆开自己一个个组件来组装,然后完成一个微型的Linux系统.下面,让我们来实现吧..写的不好 ...

  5. windows 7蓝屏解决办法

    1.通过工具打开出现蓝屏原因的dmp文件,找到原因 Unable to load image \SystemRoot\system32\ntkrnlpa.exe, Win32 error 0n2 2. ...

  6. SQL注入攻击三部曲之进阶篇

    SQL注入攻击三部曲之进阶篇 通过入门篇的学习,我们知道了SQL注入攻击的判断方法,但是如果想侵入网站,获取网站的机密内容,那么仅靠入门篇的知识是无法达到的.本篇文章我们将进一步的分析SQL注入攻击. ...

  7. 使用jsoup抓取新闻信息

    1,jsoup简介 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和 ...

  8. freemarker报错之十

    1.错误描述 <html> <head> <meta http-equiv="content-type" content="text/htm ...

  9. java 堆 栈 常量池

    java 堆中保存new 出来的对象(每个对象都包含一个与之对应的class的信息,[class信息存放在方法区]),堆中分配的内存,有虚拟机的自动垃圾回收器管理,栈内存只对其所属线程可见. java ...

  10. pat1061-1070

    1061 我想吐槽这题的题意不够清楚,不过下次得长记性,对于模糊的题意要大胆猜测,而不是固执己见 #include<iostream> #include<cstdio> #in ...