春蚕到死丝方尽,蜡炬成灰泪始干

              ——无题

这里介绍两个比较难的算法:

1、堆排序

2、分治并归排序

先说堆。

这里请大家先自行了解完全二叉树的数据结构。

堆是完全二叉树。大顶堆是在堆中,任意双亲值都大于(或等于)其孩子值,就称其为大顶堆。

堆排序的步骤:

1、把数组想象成一个堆。数组的index+1就是其对应在堆中的序号

2、调堆中各值的顺序,得到大顶堆

3、将堆首位值与堆末尾值交换,最大值排序完毕

4、将堆得大小减1,重复步骤2和步骤3,直到堆中只剩下一个元素。排序完毕

上代码:

 public class HeapSort {

     public static void heapSort(int[] arr){
//建立完全二叉树,从最后一个双亲开始调整双亲值,直到根,调整完毕后大顶堆建立完成
for (int i = arr.length >> ; i > ; i --) {
heapAdjust(arr, i, arr.length);//调用堆要从1到length才符合堆的定义
}
//堆顶和堆低交换,获取最大值,然后调整大顶堆
for (int i = arr.length - ; i > ; i--) {
arr[i] = arr[i]^arr[];
arr[] = arr[i]^arr[];
arr[i] = arr[i]^arr[];
heapAdjust(arr, , i);//因为堆计数要从1开始,所以size = endIndex + 1
}
}
//调整大顶堆.先找左子,然后和右子比,取值大的,在和双亲自己比,自己比儿子大,break,否则交换.注意:根要从1开始才能找到左子
public static void heapAdjust(int[] arr, int parents, int size){
int j;//孩子们的标记是j,索引全部-1
int i = parents;//双亲是i,索引全部-1
while (i << <= size) {
j = i << ;//左子
if (j + <= size) {//有右子
if (arr[j - ] < arr[j + -])
j ++;
}
if (arr[i - ] > arr[j - ])
break;
arr[i-] = arr[i-]^arr[j-];
arr[j-] = arr[i-]^arr[j-];
arr[i-] = arr[i-]^arr[j-];
i = j;//儿子变为父亲,这里不知道是左子还是右子,所以不能直接通过for循环的迭代步骤<<i调整i值,如果是右子的话就错了(右子<<1+1)
}
}
}

再说分治并归排序

这里先要了解什么是递归

 public class MergingTest {

     public static void main(String[] args) {
mSort(, );
}
private static void mSort(int left, int right) {
int m = (left + right)/;
if (left == right) {
System.out.println(left);
return;
}
mSort(left, m);
mSort(m+, right);
}
}

这几行代码是并归算法的核心。运行代码将输出0123456789,虽然看上去很简单,但是如果真能明白,说明你已经完全理解递归的思想了,写出并归算法也就不在话下了。

为什么会输出0123呢?

代码执行的走向:1→2→4→2→5→2→1→3→6→3→7→3→1→return

能领悟这个东西就好办了,上代码:

 public class MergingSort {

     public static void mergingSort(int[] arr) {
int[] temp = new int[arr.length];
      //temp是相当于一张牌,通过left,m,right在逻辑上分成两个数组,进行分治排序,arr是原数组,对数组排序不传数组怎么行?!
mSort(arr, temp, , arr.length-);
}
private static void mSort(int[] arr, int[] temp, int left, int right) {
      //这里的分组逻辑没有使用到temp和arr,而是把它们作为参数传入merge方法
int m = (left+right)/ ;
if (left == right) {
return;
}
mSort(arr, temp, left, m);
mSort(arr, temp, m+, right);
merge(arr,temp,left,m,right);
}
private static void merge(int[]arr, int[] temp, int left, int m, int right) {
      //分治排序极其简单,已知两个有序数组,要把他们合并成一个有序数组,用什么方法都不用说,大家一想就知道了。
for (int c = ;c < arr.length;c++){
temp[c] = arr[c];
}
for (int p = ; p < temp.length; p++) {
System.out.println("temp["+p+"] = " + temp[p]);
}
int i = left;
int j = m + ;
int k = left;
while (i<=m && j<=right) {
        //使用分支结构,把每摞牌最小的那个挑出来给arr
if (temp[i] < temp[j]) {
arr[k++] = temp[i++];
}
if (temp[j] < temp[i]) {
arr[k++] = temp[j++];
}
}
        //使用分支结构,把剩下的那摞牌都塞给arr
if (i > m) {
while (j <= right) {
arr[k++] = temp[j++];
}
}
if (j > right) {
while (i <= m) {
arr[k++] = temp[i++];
}
}
} }

Java学习笔记——排序算法之进阶排序(堆排序与分治并归排序)的更多相关文章

  1. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  2. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  3. java学习笔记13--比较器(Comparable、Comparator)

    java学习笔记13--比较器(Comparable.Comparator) 分类: JAVA 2013-05-20 23:20 3296人阅读 评论(0) 收藏 举报 Comparable接口的作用 ...

  4. java学习笔记11--集合总结

    java学习笔记系列: java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Ob ...

  5. 20145330第八周《Java学习笔记》

    20145330第八周<Java学习笔记> 第十五章 通用API 通用API 日志:日志对信息安全意义重大,审计.取证.入侵检验等都会用到日志信息 日志API Logger:注意无法使用构 ...

  6. 20145330第五周《Java学习笔记》

    20145330第五周<Java学习笔记> 这一周又是紧张的一周. 语法与继承架构 Java中所有错误都会打包为对象可以尝试try.catch代表错误的对象后做一些处理. 使用try.ca ...

  7. java学习笔记04--数组

    java学习笔记04--数组 数组复制的方法是使用System类提供的arraycopy()方法,其语法如下: System.arraycopy(Object src, int srcPos, Obj ...

  8. 20145230《java学习笔记》第七周学习总结

    20145230 <Java程序设计>第7周学习总结 教材学习内容 Lambda语法概览 我们在许多地方都会有按字符串长度排序的需求,如果在同一个方法内,我们可以使用一个byName局部变 ...

  9. Java学习笔记之---方法和数组

    Java学习笔记之---方法与数组 (一)方法 (1)什么是方法? 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 (2)方法的优点 使程序变得更简短而 ...

  10. java学习笔记之基础篇

    java选择语句之switch   //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...

随机推荐

  1. TensorFlow安装-windows系统

    官方各版本的安装说明:https://www.tensorflow.org/install/ 本文介绍如何在windows环境下安装tensorflow, 跑起来简单的demo. 1.安装python ...

  2. ceph集群安装

    所有 Ceph 部署都始于 Ceph 存储集群.一个 Ceph 集群可以包含数千个存储节点,最简系统至少需要一个监视器和两个 OSD 才能做到数据复制.Ceph 文件系统. Ceph 对象存储.和 C ...

  3. Java基础之J2EE规范

    什么是J2EE? 在企业级应用中,都有一些通用企业需求模块,如数据库连接,邮件服务,事务处理等.既然很多企业级应用都需要这些模块,一些大公司便开发了自己的通用模块服务,即中间件.这样一来,就避免了重复 ...

  4. Ubuntu上手动安装Kubernetes

    背景 两台Ubuntu16.04服务器:ip分别为192.168.56.160和192.168.56.161.. Kubernetes版本:1.5.5 Docker版本:1.12.6 etcd版本:2 ...

  5. CSS3 转换、过渡和动画

    一.转换 1.属性:transform 取值:none/transform-function(转换函数) 注意:如果要实现多个转换函数的话,可以用空格分开若干transform-function 2. ...

  6. 聊天界面使用IQKeyboardManager导航栏及整个页面上移的解决方法

    问题: 使用第三方库IQKeyboardManager时会使整个页面上移,导航栏页偏移出了显示范围.在聊天界面就会使得上面的消息看不到. 解决方法: 首先说明:在聊天界面使用IQKeyboardMan ...

  7. node.js框架express的安装

    node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...

  8. 表单的序列化ajax

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. Linux配置tomcat (centos配置java环境 tomcat配置篇 总结三)

    ♣下载安装tomcat7 ♣设置启动和关闭 ♣设置用户名和密码 ♣发布java web项目 声明:这篇教程是建立在前两篇教程的基础上的,所以,还没安装工具和jdk,可以先看这个系列的前面两篇(去到文末 ...

  10. 关于centos 7 systemctl自定义服务笔记

    通过添加 Restart=always RestartSec=2s StartLimitBurst=10 实现systemctl服务崩溃自动重启