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

              ——无题

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

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. java安装1335错误解决办法(亲测)

    心血来潮想了解一下java,结果一开始就碰到了让心"恶心"的1335错误. 废话不多说,直接看下面: 你可以先尝试在这个链接下载java.exe文件 http://www.orac ...

  2. IDMC制造业ERP业务场景测试之一——硅钢片制造业务流程测试

    一.测试地址 硅钢片业务测试数据库地址为:http://www.bonawifi.com,测试数据库名字为SiliconSteelSheet,测试账号:用户名demo ,密码demo 二.业务说明 根 ...

  3. ng自带的表单验证

    几点注意:使用ng的表单验证,需要给form,input,textarea一个name 要求:验证输入框的内容(长度,正则,必填,),当验证不通过的时候,就禁用提交按钮 使用的验证:ng-maxlen ...

  4. 搞定:Enter passphrase for key提示

    使用ssh-genkey生成公用key,但是自己使用时会多次提示,Enter passphrase for key,这儿给出如何解决. 在${HOME}/.bashrc中增加如下代码: alias a ...

  5. Centos7上安装Kubernetes集群部署docker

    一.安装前准备1.操作系统详情需要三台主机,都最小化安装 centos7.3,并update到最新 [root@master ~]# (Core) 角色 主机名 IPMaster master 192 ...

  6. POJ3592 Instantaneous Transference题解

    题意: 给一个矩形,矩形中某些点有一定数量的矿石,有些点为传送点,有些点为障碍.你驾驶采矿车(ore-miner truck,我也不知道是什么),从左上角出发,采尽量多的矿石,矿石不可再生.不能往左边 ...

  7. activiti 5.13 使用activiti设置用户组任务的 工作流的角色

    1.设置activiti 流程引擎的用户,组别,关系/**在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息*/ IdentityService iden ...

  8. .Net 官方学习文档

    .Net 官方学习文档:https://docs.microsoft.com/zh-cn/dotnet/articles/welcome

  9. jenkins+webhook+docker做持续集成

    简介:我们现在都流行把项目封装成docker的镜像,不过实际用的时候就会发现很麻烦,我们每次更改代码了以后都要打包成docker容器 ,事实证明项目比较多的时候真的会让人崩溃,我这边用spring c ...

  10. 卷积神经网络CNN公式推导走读

      0有全连接网络,为什么还需要RNN 图像处理领域的特殊性,      全连接网络缺点:                              RNN解决办法:      1参数太多       ...