前言:网上有很多堆排序的案例,我只想写自己堆排序。

一:堆结构

即:一个父节点最多只能有两个子节点(可以没有),如下图

图1

       图2

          图3

      图4

二: 数组与堆结构转换

假设已知堆数组   int[]  a = {9,7,6,4,5,1,3,2,}  则相应对结构如下

图5

备注: 一个父节点(pNode  为图5中的7 )和两个子节点(4(lNOde 左节点)和5(rNode 右节点))的关系

左节点: lNOde =  2*pNode   + 1  ;

右节点 :  rNode  = 2*pNode    +2 ;

三:通过已知数组建立成堆结构数组

假设已知数组   int[] a = { 7,9,6,4,5,1,3,2};

思路:对一个已知堆结构数组(长度为n)中添加一个元素,并调整该结果使之成为新的堆结构数组(长度变成 n+1)

步骤一:获取该数组的第一个元素 7 (a[0])为已知堆数组。

步骤二 :获取该数组的第下一个元素9(a[1])并添加到上一个堆结构数组中,并判断其的父节点是否大于自己,如果大于则交换父节点与自己的位置,交换后自己就在父节点的位置并把自己当成新的子节点,继续寻找父节点直至自己小于父节点并返回。如果大于则已是堆结构返回。以此类推直至成为新的堆结构。

步骤三 :重复步骤二,直至数组最后一个元素。

java实现:

/*** 建立堆模型

*

*@parama*/

private static void buildHeat(int[] a) {for (int i = 1; i < a.length; i++) { //注意我是从数组的第二个位置(即 index = 1)开始的int parentNodeIndex =getParentNodeIndex(i);int currentIndex =i;while (parentNodeIndex >= 0) {//判断子节点是否大于父节点

if (a[parentNodeIndex]

int temp =a[parentNodeIndex];

a[parentNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}else{// break; //步骤2 :自己小于父节点结束循环(while)已成为新的堆结构。>>>>>>>执行步骤3

}

currentIndex=parentNodeIndex; //步骤2 把自己当成新的子节点

parentNodeIndex=getParentNodeIndex(parentNodeIndex);

}

}

}

四:去堆(获取排序)

步骤一:因为堆顶是整个堆结构中最大的数,所以我获取堆顶的哪个数9(a[0]  如图5),并把堆中最后一个数2(如图5)放入堆顶 (此时的数组长度是原来数组长度的减一)

步骤二 :调整堆结构(因为上一个步骤把 最后一个数放入如堆顶).。

调整方法:   获取获取左右子节点,先判断是否有子节点,然后判断两个子节点的大小(假设9已经换成了2,当前它有两个子节点,7(左子节点) 6 (右子节点)),获取到最大的子节点(7),并于父节点(2)比较 ,如果子节点大于父节点,交换父节点与子节点的位置,并把当前自己成为新的父节点重复调整方法,直至没有子节点或父节点大于所有子节点。成为新的堆结构

步骤三 :重复步骤一和二 ,直至没有改结构中没有子节点。

java实现

备注:代码与步骤二的调整方法有些不同 ,因为 1)如果没有左节点 (调整结束) 就一定不会有右节点?。2)如果有右节点就一定有左节点?。3)如果只有左节点没有右节点?

//去除堆 》》即排序

for(int j = 0; j < a.length; j++) {int lastIndex = a.length - 1 -j;int currentIndex = 0;int temp2 = a[0]; //步骤1 : 获取堆结构中的最大数 并与最后一个数交换位置

a[0] =a[lastIndex];

a[lastIndex]=temp2;while(true) {//获取左节点

int leftChildNodeIndex =getLeftChildNodeIndex(currentIndex); //步骤2 获取左节点位置if(leftChildNodeIndex >=lastIndex) { //判断做节点是否有 有数//没有左节点子节点 即去堆完成

for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("没有左节点子节点 即去堆完成");break; //步骤3

}//获取右节点

int rightChildNodeIndex =getRightChildNodeIndex(currentIndex);if(rightChildNodeIndex >=lastIndex) { //获取右节点//没有右子节点 但有左节点 需要进行 交换

if (a[leftChildNodeIndex] >a[currentIndex]) {//判断左子节点 大于父节点 需要交换位置

int temp =a[leftChildNodeIndex];

a[leftChildNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("没有右子节点 但有左节点");break; //步骤3

}//即有左节点又有有节点//先判断左右节点的大小 返回大节点

int whichIndexBig = a[leftChildNodeIndex] > a[rightChildNodeIndex] ?leftChildNodeIndex : rightChildNodeIndex;//判断子节点是否大于符节点

if (a[whichIndexBig] >a[currentIndex]) {//子节点大于父节点 需要交换子父节点的位置

int temp =a[whichIndexBig];

a[whichIndexBig]=a[currentIndex];

a[currentIndex]=temp;

}//当前父节点

currentIndex =whichIndexBig; //

}

}

五 完整代码实现如下

packagecom.jinliang.sort;public classHeatSort {public static voidmain(String[] args) {int[] a = { 7,4,6,9,5,1,3,2};//创建堆数组

buildHeat(a);for (int j = 0; j < a.length; j++) {

System.out.print(a[j]+ ",");

}

System.out.println("建队完成");//int[] a = {42, 88, 77, 76, 66, 55, 64, 52, 45, 54, 34, 2, 32, 12, 35, 1, 22, 21, 34, 3};//去除堆 》》即排序

for(int j = 0; j < a.length; j++) {int lastIndex = a.length - 1 -j;int currentIndex = 0;int temp2 = a[0];

a[0] =a[lastIndex];

a[lastIndex]=temp2;while(true) {//获取左节点

int leftChildNodeIndex =getLeftChildNodeIndex(currentIndex);if(leftChildNodeIndex >=lastIndex) {//没有左节点子节点 即去堆完成

for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("没有左节点子节点 即去堆完成");break;

}//获取右节点

int rightChildNodeIndex =getRightChildNodeIndex(currentIndex);if(rightChildNodeIndex >=lastIndex) {//没有右子节点 但有左节点 需要进行 交换

if (a[leftChildNodeIndex] >a[currentIndex]) {//判断左子节点 大于父节点 需要交换位置

int temp =a[leftChildNodeIndex];

a[leftChildNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("没有右子节点 但有左节点");break;

}//即有左节点又有有节点//先判断左右节点的大小 返回大节点

int whichIndexBig = a[leftChildNodeIndex] > a[rightChildNodeIndex] ?leftChildNodeIndex : rightChildNodeIndex;//判断子节点是否大于符节点

if (a[whichIndexBig] >a[currentIndex]) {//子节点大于父节点 需要交换子父节点的位置

int temp =a[whichIndexBig];

a[whichIndexBig]=a[currentIndex];

a[currentIndex]=temp;

}//当前父节点

currentIndex =whichIndexBig;

}

}//输出排序后的数组

for (int i = 0; i < a.length; i++) {

System.err.print(a[i]+ ",");

}

}/*** 建立堆模型

*

*@parama*/

private static void buildHeat(int[] a) {for (int i = 1; i < a.length; i++) {int parentNodeIndex =getParentNodeIndex(i);int currentIndex =i;while (parentNodeIndex >= 0) {//判断子节点是否大于父节点

if (a[parentNodeIndex]

堆排序java实例_堆排序(示例代码)相关推荐

  1. 堆排序 java实现_堆排序Java实现(递归方式非递归方式)

    很早就学习了堆排序但当时没有用代码实现,现在再去想实现已经忘光光啦┑( ̄Д  ̄)┍,于是就去网上搜了一番,发现没有一篇我能认真看完的文章,没办法就是没耐心,就是笨呗...好了,言归正传= ̄ω ̄= 了解 ...

  2. java工程化_(二)Java工程化--Maven实践(示例代码)

    Maven项目版本号 默认版本号: 1.0-SNAPSHOT 最佳实践是约定该版本为不稳定版本,如果发布一定要删除; 建议的版本规则: 主版本号.次版本号.增量版本号- 如:1.0.0-RELEASE ...

  3. 堆排序算法讲解视频java版_堆排序算法的讲解及Java版实现

    堆是数据结构中的一种重要结构,了解了"堆"的概念和操作,可以快速掌握堆排序. 堆的概念堆是一种特殊的完全二叉树(complete binary tree).如果一棵完全二叉树的所有 ...

  4. java 文件下载示例_文件下载示例代码(JAVA)

    后台代码 public void exportFile() { File file = new File("模板地址"); FileInputStream fin = null; ...

  5. 堆排序的java实现_堆排序(java实现)

    public class heapSort01 { //构建大根堆:将array看成完全二叉树的顺序存储结构 private int[] buildMaxHeap(int[] array){ //从最 ...

  6. tcp java实例_实现了基于TCP的Java Socket编程实例代码

    实现了基于TCP的Java Socket编程,功能很简单:客户端向服务器端输出一名话"connect",服务器端接收输出到控制台并向客户端输出一名话"Hello" ...

  7. 微信用户绑定java实例_第三方网站微信登录java代码实现

    前两个星期在公司中的项目加上了微信登录.绑定的功能,在这里做个记录! 一.开发前知识 1.微信开放平台与微信公众平台的区别 1.1 微信公众平台: ② 微信公众平台面向的是普通的用户,比如自媒体和媒体 ...

  8. java移动公司计算话费_话费充值示例代码

    话费充值 package api.binstd.mobilerecharge; /** * 话费充值 */ import java.io.UnsupportedEncodingException; i ...

  9. java n个点 凸多边形_使用JAVA判断凸多边形的示例代码

    以HDU2108为例,去AC吧. //点逆序输入 import java.util.Scanner; //1s public class HDU2108 { public static void ma ...

最新文章

  1. 整理前端工作中的可复用代码(二):拓展spark-md5,支持计算网络文件md5
  2. webpack 图片压缩不起作用_理论|webpack2 终极优化
  3. mysql Communications link failure druid
  4. shutil python_shutil模块
  5. 原型模式 java 深浅_Java设计模式——原型模式
  6. Android之自定义checkbox样式
  7. mysql数据库内置函数大全_(MariaDB)MySQL内置函数大全
  8. 道理都明白,为什么很难做到
  9. [转载] python 中NumPy和Pandas工具包中的函数使用笔记(方便自己查找)
  10. Eviews6 7 软件安装包
  11. php用空格分隔字符串,分割字符串空格
  12. 摄影测量——单片空间后方交会
  13. java 图片画框并读取成base64数据
  14. Android中文件的读写---assets和raw下的资源文件
  15. 绑定美版office365密钥_美版Microsoft/微软Office 365个人版怎么激活?
  16. Google Chrome浏览器的回退功能快捷键
  17. 如果一份工作让你时常感到焦虑,你会不会立马辞职?
  18. python和C++语言哪个难学
  19. VS2010中添加Flash控件
  20. 震惊!小伙竟然用python找出了马大师视频中的名场面

热门文章

  1. 番茄花园win11 32位专业版镜像v2021.08
  2. matlab矢量角度,MATLAB矢量,角度,图
  3. Java中的return this
  4. springboot+shiro:ShiroConfiguration配置
  5. SXSSFWorkbook使用——使用excel模板
  6. js面向对象与java面向对象的区别,被坑了,js语法跟Java面向对象语法还是有区别的...
  7. php表单验证内容不能为空,php校验表单检测字段是否为空的方法_PHP教程
  8. 如何使用explain进行SQL语句调优
  9. Java NIO————NIO 简介
  10. Java并发编程实战————恢复中断