堆排序Java示例

堆排序是指利用堆这种数据结构所设计的一种排序算法。堆的特点是子结点总是小于(或者大于)它的父节点,根节点最大的堆叫做最大堆,根节点最小的堆叫做最小堆。根据升序或降序的排序需求选择使用最大堆还是最小堆,本文以升序排列为例,所以选用最大堆。

堆排序的基本思想是:将原始序列先调整为一个最大堆,这样根顶元素就是整个序列的最大值;将其与末尾元素交换,这样该序列最大元素就归位了;将剩下的N-1个元素再调整为最大堆,再次交换根顶元素和本次末尾元素,这样次大值也归位了;反复循环,直到整个序列都有序。

java示例:

public class HeapSort {

    public static void main(String[] args) {
        int[] arr = {1,3,2,6,4,66,32,65,34,67,45,77,78,36,56};
        System.out.println("排序前:");
        System.out.println(Arrays.toString(arr));
        sort(arr);
        System.out.println("排序后:");
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] arr) {
        //构建最大堆
        for (int i = arr.length/2 - 1; i >= 0; i--) {
            handleHeap(arr, i, arr.length);//从最末尾的非叶子节点,自右至左,自下而上调整
        }
        for (int j = arr.length - 1; j > 0; j--) {
            swap(arr, 0, j);//交换根顶元素和末尾元素
            handleHeap(arr, 0, j);//重新调整成最大堆
        }
    }

    //调整最大堆(建立在最大堆已构建的基础上)
    public static void handleHeap(int[] arr, int i, int length) {
        int temp = arr[i];//先取出当前元素i
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//从i结点的左子结点开始,也就是2i+1处开始
            if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if (arr[k] > temp) {//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;//将temp值放到最终的位置
    }

    //交换数组中两个元素
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

执行结果:

排序前:
[1, 3, 2, 6, 4, 66, 32, 65, 34, 67, 45, 77, 78, 36, 56]
排序后:
[1, 2, 3, 4, 6, 32, 34, 36, 45, 56, 65, 66, 67, 77, 78]

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/liuyunyihao/article/details/83859791