博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构——堆排序(使用Java)
阅读量:6242 次
发布时间:2019-06-22

本文共 2701 字,大约阅读时间需要 9 分钟。

一、简介

  堆排序(HeapSort)是选择排序的改进版,它可以减少在选择排序中的比较次数,进而减少排序时间,堆排序法用到了二叉树的技巧,它利用堆积树来完成,堆积是一种特殊的二叉树,可分为大根堆和小根堆。

  大根堆需要具备的条件:

它是一棵完全二叉树

所有节点的值都大于或等于它左右子节点的值

树根是堆积数中最大的

小根堆需要具备的条件:  

它是一棵完全二叉树

所有节点的值都小于或等于它左右子节点的值

树根是堆积数中最小的

二、核心思想

  利用大根堆(小根堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。

    其基本思想为(大根堆):

    1)将初始待排序关键字序列(R1,R2....Rn)构建成大根堆,此堆为初始的无须区;

    2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n]; 

    3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

    操作过程如下:

     1)初始化堆:将R[1..n]构造为堆;

     2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。

    因此对于堆排序,最重要的两个操作就是构造初始堆和调整堆,其实构造初始堆事实上也是调整堆的过程,只不过构造初始堆是对所有的非叶节点都进行调整。

 

三、图例说明

建立初始堆:

然后,交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……

  重复此过程,直至得到有序序列

  

四、代码实现

1 private static void heapSort(int[] a) { 2         int n=a.length;//获取数组长度 3         int temp;//用于交换数据 4         //构建出初始堆 5         for (int i = n/2; i >=0; i--) { 6             addDatetoHeap(a,i,n-1); 7         } 8         System.out.println(); 9         System.out.print("原始堆:");10         for (int i = 0; i < a.length; i++) {11             System.out.print(a[i]+"  ");12         }13         System.out.println();14         for (int i = n-2; i>=0; i--) {15             //将树根排到有序序列中,然后继续构建堆16             temp=a[i+1];17             a[i+1]=a[0];18             a[0]=temp;19             addDatetoHeap(a, 0, i);20         }21     }22 23     private static void addDatetoHeap(int[] a, int i, int n) {24         25         int temp=a[i];//记录父节点26         int post=0;//用于判断父节点是否比子节点达27         int j=2*i;//记录子节点28         while(j<=n&&post==0){29             if(j
=a[j]){
//如果树根较大就结束比较过程35 post=1;36 }else {37 a[j/2]=a[j];//树根较小,继续比较38 j=2*j;39 }40 a[j/2]=temp;41 } 42 }43 public static void main(String[] args) {44 int[]a=new int[10];45 Random ran=new Random();46 System.out.println("排序前数组");47 //使用Random方法生成一个随机数组并输出48 for (int i = 0; i < a.length; i++) {49 a[i]=ran.nextInt(100);50 System.out.print(a[i]+" ");51 }52 //调用排序方法53 heapSort(a);54 //输出排序后方法55 System.out.println("排序后数组");56 for (int i = 0; i < a.length; i++) {57 58 System.out.print(a[i]+" ");59 }60 }
View Code

 

 五、算法分析

  1. 所有情况下时间复杂度均为O(nlogn)。
  2. 堆排序是不稳定排序法。
  3. 只需一个额外的空间,空间复杂都为O(1).

 

转载于:https://www.cnblogs.com/TYDBLOG/p/7691386.html

你可能感兴趣的文章
向Java开发者介绍Scala
查看>>
【软考点点】计算机基础知识
查看>>
hdu2066一个人的旅行(多源点多汇点的最短路径问题)
查看>>
老猪带你玩转android自定义控件一——打造最简单viewpagerindicator
查看>>
【hibernate框架】性能优化之list_iterate的不同之处
查看>>
block高级功能
查看>>
把钱投资自己的头脑上(一)
查看>>
iOS调试奇巧淫技(二)之LLDB
查看>>
[LeetCode]173.Binary Search Tree Iterator
查看>>
整合大量开源库项目(五)跳动的TextView JumpingBeans,良好体验的滚动栏ConvenientBanner...
查看>>
some utility discovered by Linux yum search all tcp, epel.repo
查看>>
SecureCRT连接ubuntu时,中文显示乱码的解决方法
查看>>
quartz---我为什么要使用quartz
查看>>
Mybatis参数传递
查看>>
Android 6.0 在运行时请求权限
查看>>
ES6语法(三) 对象
查看>>
Swift4 func
查看>>
create-react-app2.x 自定义配置(less 按需加载 装饰器)
查看>>
第一个掘金文章
查看>>
最酷的深度学习聊天机器人资源集合
查看>>