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

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. JVM笔记6-垃圾回收概述

    JVM进行垃圾回收时要考虑哪的问题如下: 1.如何判定对象为垃圾对象? 1.引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,引用失效的时候,计数器的值就-1, ...

  2. WPF将RGB转为HSL的工具类

    class HSLColor     {         private int _alpha = 255;         public int _hue = 0;         public d ...

  3. linux yum源配置及vim运用

    redhat7默认没有yum模板,需要自己创建[root@localhost ~]# mount /dev/cdrom /root/iso/(挂载镜像)mount: /dev/sr0 写保护,将以只读 ...

  4. python环境jieba分词的安装

    我的python环境是Anaconda3安装的,由于项目需要用到分词,使用jieba分词库,在此总结一下安装方法. 安装说明======= 代码对 Python 2/3 均兼容 * 全自动安装:`ea ...

  5. VS2010 C++学习(5):基于DirectShow的视频预览录像程序

    VS2010 C++学习(5):基于DirectShow的视频 预览录像程序 学习VC++编制的基于DirectShow视频捕获程序,主要练习基于DirectShow程序的应用. 一.         ...

  6. 错误代码: 1248 Every derived table must have its own alias

    1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:SELECT stu_id, (SELECT stu_name FROM t ...

  7. dojo加载树报错

    1.错误描述    error loading undefined children.    TypeError:this._arrayOfTopLevelItems is undefied. 2.错 ...

  8. Android的sdk、api及工程目录说明

    SDK下包的说明1:add-ons:Android开发需要的第三方文件和软件库2:docs:Android的文档.包括开发指南.API参考.资源等3:extras:扩展的附加包4:platforms: ...

  9. CF198 div1 D - Iahub and Xors

    简单说就是左边x,y按照奇偶分为四种对于答案的影响都是不相关的 #include<bits/stdc++.h> using namespace std; typedef long long ...

  10. freemark声明变量,boolean,date,date日期格式转换成String类型的(五)

    <br/>assign用来定义变量<#assign name="刘德华"><br/> 获取assign定义变量的值:${name} <br ...