最近开始学习排序的相关知识,计划以后每天都要整理一个排序的算法。
今天整理了堆排序的排序算法,起初自己并不了解堆排序的相关过程,在阅读了博客http://www.cnblogs.com/luchen927/archive/2012/03/08/2381446.html之后,才对这方面的知识有所了解,在看了此博客的指导之后,感觉他写的代码有点问题,所以就自己重新写了一个。
其中最需要注意的就是:
根据根结点i(i为数组中的下标)来计算其左右孩子的坐标时,left = i * 2 + 1, right = i * 2 + 2, 因为根节点是从数组0位置开始的。
import java.util.Arrays; /** * 堆排序的介绍: * 堆排序对于记录数较少的文件并不提倡,但对n较大的文件还是很有效的。 * 其最坏情况下的时间复杂度为:O(nlogn), 在最好情况下,时间复杂度为:O(1). * 堆排序是不稳定的排序。 * * * *堆排序的具体过程: * 1 、首先从第一个非叶子节点开始,比较当前节点和其孩子节点,将最大的元素放在当前节点,交换当前节点和最大节点元素。 * 2 、将当前元素前面所有的元素都进行1的过程,这样就生成了最大堆 * 3 、将堆顶元素和最后一个元素交换,列表长度减1。由此无序区减1,有序区加1 * 4 、剩余元素重新调整建堆 * 5 、 继续3和4,直到所有元素都完成排序 * * **/ public class HeapSort{ public static void heapSort(int[] num){ if(num == null) return; int len = num.length; buildHeap(num, len); /**每次将堆顶元素放到数组最后的位置*/ while(len > 1){ swap(num, len - 1, 0); len --; adjustHeap(num, len, 0); } } /**将一个无序的数组构建成一个大顶堆*/ private static void buildHeap(int[] num, int len) { /**begin为最后一个根节点在数组中的下标*/ int begin = len / 2 -1; /**依次遍历每一个根节点,通过调整,使每一个根节点都比它的孩子结点大*/ for(int i = begin; i >= 0; i--){ adjustHeap(num, len, i); } } /**调整根节点和孩子结点的位置,使其满足大顶堆*/ private static void adjustHeap(int[] num, int len, int i) { /**获取下标为i的根节点的左孩子和右孩子在数组中的下标*/ int leftChild = i * 2 + 1; int rightChild = i * 2 + 2; /**将本次调整的最大值下标暂时记为i*/ int max = i; while(leftChild < len || rightChild < len){ /**如果num[max]的左孩子num[leftChild]比max大,将leftChild暂存在max中*/ if(leftChild < len && num[max] < num[leftChild]){ max = leftChild; } /**如果num[max]的右孩子num[rightChild]比max大,将rightChild暂存在max中*/ if(rightChild < len && num[max] < num[rightChild]){ max = rightChild; } /**如果在前面的运算中,发生过赋值*/ if(i != max){ swap(num, max, i); i = max; leftChild = i * 2 + 1; rightChild = i * 2 + 2; }else{ break; } }//while(leftChild < len || rightChild < len) }//private static void adjustHeap() /**将数组中num[x]和num[y]位置交换*/ private static void swap(int[] num, int x, int y) { num[x] = num[x] ^ num[y]; num[y] = num[x] ^ num[y]; num[x] = num[x] ^ num[y]; } public static void main(String[] args) { int[] num = {0, 9, 7, 0, 0, 6, -40, 200}; HeapSort.heapSort(num); System.out.println(Arrays.toString(num)); } }
原文地址:http://blog.csdn.net/junwei_yu/article/details/38736181