排序笔记_4(自上而下、自底而上的归并排序)
来源:互联网 发布:大连理工大学网络教育 编辑:程序博客网 时间:2024/05/02 02:22
/*** * 归并排序(分治思想的典型应用): * * 分为自上而下(递归)和自下而上(非递归,比较适合用链表组织的数据)的算法 * * 特点: * * 保证将任意长度为N的数组排序所需的时间和NlogN成正比; * 处理有百万、千万级别的元素个数的数组不成问题。 * * 缺点: * * 需要的额外空间和N成正比。 * * 改进方案: * ①对小规模的子数组使用插入排序 * ②测试数组是否有序 * (加一个判断条件,如果a[mid]小于a[mid+1],我们就认为是有序的, * 从而跳过merge()方法,这个改动不会影响递归的调用,但是运行时间就变成线性的了。) * * 自上而下(递归): * 将一个大问题分割成小问题分别解决,然后用所有小问题的答案解决大问题的答案。 * * 自下而上(非递归): * 先归并那些微型数组,然后再成对归并得到的子数组,直到将整个数组归并到一块。 * (基本思想:首先进行两两归并,把每个元素看成一个大小为1的子数组, * 然后是四四归并,将两个大小为2的数组归并成一个有4个元素的数组, * 然后是八八归并,一直下去。) */package com.chapter_two;/*** * 自顶向下的归并排序 * * @author LuodiJack * */public class Merge { @SuppressWarnings("rawtypes") private static Comparable[] aux;// 辅助数组 /*** * 原地归并的抽象方法: 将两个有序数组归并成更大的有序数组。 * * @param a * 需要归并的数组。 * @param low * 数组的下界,实际的索引值。 * @param mid * 数组的中部,实际的索引值。 * @param high * 数组的上界,实际的索引值。 */ @SuppressWarnings("rawtypes") private static void merge(Comparable[] a, int low, int mid, int high) { int i = low; int j = mid + 1; for (int k = low; k <= high; k++) { aux[k] = a[k]; } for (int k = low; k <= high; k++) { if (i > mid) {// 右边剩下,将右边赋值给数组。 a[k] = aux[j++]; } else if (j > high) {// 左边剩下,将左边赋值给数组。 a[k] = aux[i++]; } else if (Template.less(aux[i], aux[j])) {// 左边的小,就取左边的。 a[k] = aux[i++]; } else {// 右边的小,就取右边的。 a[k] = aux[j++]; } } } /*** * 自顶向下的归并排序函数 * * @param a * 需要排序的数组 * */ @SuppressWarnings("rawtypes") public static void sort(Comparable[] a) { aux = new Comparable[a.length];// 一次性的分配辅助空间 sort(a, 0, a.length - 1); } @SuppressWarnings("rawtypes") private static void sort(Comparable[] a, int low, int high) { if (high <= low) { return; } int mid = low + (high - low) / 2; sort(a, low, mid);// 对左边的归并排序 sort(a, mid + 1, high);// 对右边的归并排序 merge(a, low, mid, high);// 合并两边的数组 }}
package com.chapter_two;/*** * 自底而上的归并排序 * * @author LuodiJack * */public class MergeBU { @SuppressWarnings("rawtypes") private static Comparable[] aux;// 辅助数组 /*** * 原地归并的抽象方法: 将两个有序数组归并成更大的有序数组。 * * @param a * 需要归并的数组。 * @param low * 数组的下界,实际的索引值。 * @param mid * 数组的中部,实际的索引值。 * @param high * 数组的上界,实际的索引值。 */ @SuppressWarnings("rawtypes") private static void merge(Comparable[] a, int low, int mid, int high) { int i = low; int j = mid + 1; for (int k = low; k <= high; k++) { aux[k] = a[k]; } for (int k = low; k <= high; k++) { if (i > mid) {// 右边剩下,将右边赋值给数组。 a[k] = aux[j++]; } else if (j > high) {// 左边剩下,将左边赋值给数组。 a[k] = aux[i++]; } else if (Template.less(aux[i], aux[j])) {// 左边的小,就取左边的。 a[k] = aux[i++]; } else {// 右边的小,就取右边的。 a[k] = aux[j++]; } } } /*** * 自底向上的归并排序函数 * * @param a * 需要排序的数组 * */ @SuppressWarnings("rawtypes") public static void sort(Comparable[] a) {// 进行两两归并 int N = a.length; aux = new Comparable[a.length];// 一次性的分配辅助空间 for (int sz = 1; sz < N; sz = sz + sz) {// sz子数组大小 for (int low = 0; low < N - sz; low += sz + sz) {// low: 子数组索引 merge(a, low, low + sz - 1, Math.min(low + sz + sz - 1, N - 1)); } } }}
0 0
- 排序笔记_4(自上而下、自底而上的归并排序)
- 小白学算法2.5.1——归并排序(自底而上)
- 归并排序(自上向下)
- 归并排序--自上而下和自下而上两种方法的实现
- 动态规划 钢条切割问题 两种方法 自底而上 自上而下的方法
- 自底向上的归并排序
- 自底向上的归并排序
- 自底向上的归并排序
- 自底向上的归并排序算法
- 归并排序(上)
- 归并排序的自底向上改进-使用插入排序
- 自底向上归并排序
- 自顶向下的归并排序和自底向上的归并排序
- 小白学算法2.5——归并排序(自顶而下)
- 链表的自底向上归并排序
- 图示经典算法--自底向上的归并排序
- 算法之自底向上的归并排序
- 3-4 自底向上的归并排序算法
- Nginx学习笔记——安装起步
- Stanford 机器学习 Week3 作业 Logistic Regression
- Office Web Apps安装部署
- Spring核心组件
- eerTcirtemmyS.101
- 排序笔记_4(自上而下、自底而上的归并排序)
- C#中的增删改查
- poj 1050 To the Max & uva 108
- 犀牛书随手记-06
- 学习笔记--数论大杂烩 (看心情更新)
- 2186: [Sdoi2008]沙拉公主的困惑 线性筛素数+欧拉函数+乘法逆元
- 2016年的希望
- HDU 4185 Oil Skimming(二分图最大匹配)
- 04环信聊天界面 - 接收方cell的布局