排序之堆排序(Java)
Posted 念奕玥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序之堆排序(Java)相关的知识,希望对你有一定的参考价值。
堆排序是利用堆这种数据结构所设计的一种排序算法。堆实际上是一个完全二叉树结构。 完全二叉树:假设一个二叉树的深度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边。
堆又分两种:
- 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
- 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
堆排序的核心步骤:
- 将待排序的数组初始化为大顶堆,该过程即建堆。
- 将堆顶元素与最后一个元素进行交换,除去最后一个元素外可以组建为一个新的大顶堆。
- 第2步堆顶元素跟最后一个元素交换后,新建立的堆不是大顶堆,需要重新建立大顶堆。重复上面的处理流程,直到堆中仅剩下一个元素。
具体排序过程:
对于堆节点的访问:
父节点 i 的左子节点的位置:(2*i+1);
父节点 i 的右子节点的位置:(2*i+2);
子节点 i 的父节点所在层数:(i-1)/2;
(以上三个位置可以自己画一个0~n的二叉树推一推)
public class heapsort {
public static void main(String[] args) {
int[] arr = {13,5,2,8,32,56,32,421,78,4};
sort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\\t");
}
}
private static void sort(int[] arr){
//i必须>0,不能是>=0。避免最后一次交换把最小值位置放错
for (int i = arr.length-1; i >0; i--) {
maxHeap(arr,i);//此时堆顶是最大数
//堆顶与当前堆的最后一个元素进行交换
int temp=arr[0];
arr[0]=arr[i];
arr[i]=temp;
}
}
/**
* 【建立大顶堆】将最大值放置在堆顶
* @param arr 待排序的数组
* @param n 数组长度-1
*/
private static void maxHeap(int[] arr,int n){
int child;
//第一个非叶子节点(n-1)/2
for (int i = (n-1)/2; i>=0; i--) {
//左子节点位置
child=2*i+1;
//若存在右子节点,且左子节点<右子节点
//让child代表右子节点(较大值)
if(child!=n && arr[child]<arr[child+1]) child++;
//父节点若小于子节点中的最大值,则进行交换
if (arr[i]<arr[child]){
int temp= arr[i];
arr[i]=arr[child];
arr[child]=temp;
}
}
}
}
以上是关于排序之堆排序(Java)的主要内容,如果未能解决你的问题,请参考以下文章