排序算法(七):JAVA实现堆排序

来源:互联网 发布:mac os 官方镜像 编辑:程序博客网 时间:2024/05/20 02:25

  堆的定义:如果一棵完全二叉树,其父节点的值总是它的两个子节点的值,就称这个树为堆。其中,如果根节点的值最大,成为大顶堆;根节点的值最小,成为小顶堆。
  堆排序是一种树形选择排序,其原理是:将给定的初始序列看做是一个顺序存储的二叉树,然后将其构造成大顶堆或者小顶堆,此时,根节点元素为最大值或最小值,将根节点元素与末尾元素交换;在将末尾元素之前的节点重新构造成大顶堆或小顶堆,如此反复,最后序列就排序成有序序列了。
  代码实现如下:
  代码中构建的是小顶堆,按照上述步骤来排序,最后是由大到小的顺序;如果是构建大顶堆,按照上述步骤排序,最后将是由小到大的排序。

package my.java.sorts;public class HeapSort {    public static void main(String[] args) {        int[] arr = {10,4,1,3,6,9,2,7,8,5};             heapSort(arr);        for (int i : arr) {            System.out.println(i);        }    }    private static void heapSort(int[] arr) {        /*         *1、如何构造大顶堆或者小顶堆?         *2、如何删除堆顶元素?         *3、如何对剩下的堆元素进行重新排序?         */        for(int i = 0;i < arr.length;i++){        //构建小顶堆            creatMinHeap(arr,arr.length-1-i);        //交换堆顶元素和末尾元素            swap(arr,0,arr.length-1-i);        }    }    //构建小顶堆的方法    private static void creatMinHeap(int[] arr, int lastIndex) {        int j;        //int small = 0;        int smallIndex;        int rightIndex;        //从最后一个有子节点的节点开始向前遍历,i和j指的是节点数,节点数比角标大1        for(int i = (lastIndex+1)/2;i >= 1;i--){            j = i;            while(2 * j <= lastIndex + 1){ //判断该节点是否有子节点                if(2 * j + 1 <= lastIndex + 1){//如果右子节点存在                    //记录较小的节点                    if(arr[2*j-1] > arr[2*j]){                        smallIndex = 2*j;//左节点和右节点比较                    }else{                        smallIndex = 2*j-1;                    }                                           if(arr[j-1] > arr[smallIndex]) swap(arr,j-1,smallIndex);//父节点和最小的子节点交换                          }else{                if(arr[j-1] > arr[2*j-1]) swap(arr,j-1,2*j-1);//父节点和最小的子节点交换            }                j++;            }        }       }    //节点值交换的方法    private static void swap(int[] arr, int i, int j) {        int tmp = arr[i];        arr[i] = arr[j];        arr[j] = tmp;       }}
原创粉丝点击