堆排序

此生再无相见时 提交于 2020-10-04 07:28:34

1、堆排序

  堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。

2、

  堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

3、堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了 

直接上代码:

//方法入口
public static int[] heapSort(int[] arr) {
    //构建大顶堆
    for (int i = arr.length / 2 - 1; i >= 0; i--) {
        //具体实现,整个构建大顶堆的过程是从下到上,从左到右
        adjustHeap(arr, i, arr.length);
    }

    for (int k = arr.length - 1; k > 0; k--) {
        swap(arr, 0, k);
        adjustHeap(arr, 0, k);
    }

    return arr;
}

private static void adjustHeap(int[] arr, int swapIndex, int length) {
    int temp = arr[swapIndex];
    //置换节点与它的两个子节点组成一个小三角,比较将最大的值,换到顶点
    for (int j = 2 * swapIndex + 1; j < length; j = 2 * j + 1) {
        // j+1<length
        if (j + 1 < length && arr[j] < arr[j + 1]) {
            j++;
        }
        if (temp < arr[j]) {
            arr[swapIndex] = arr[j];
            swapIndex = j;
        } else {
            break;
        }
    }
    arr[swapIndex] = temp;
}

private static void swap(int[] arr, int i, int k) {
    int temp = arr[k];
    arr[k] = arr[i];
    arr[i] = temp;

}

版本二

package algorithm.sorts;


import java.util.Arrays;

public class HeapSortV2 {
    public static void main(String[] args) {
        int[] arr = {1, 9, 2, 5, 23, 88, 4, 1231};
        heapSort(arr, arr.length);
        System.out.println(Arrays.toString(arr));
    }

    private static void heapSort(int[] arr, int length) {
        //构建大顶堆,此时最大的数在顶点
        buildHeap(arr, length);
        for (int i = length - 1; i >= 0; i--) {
            //把顶点与最后一位进行交换
            swap(arr, 0, i);
            //把剩下的数再构建成大顶堆
            heapify(arr, 0, i);
        }
    }

    private static void buildHeap(int[] arr, int length) {
        int startNode = length / 2 - 1;
        for (int i = startNode; i >= 0; i--) {
            heapify(arr, i, length);
        }
    }

    private static void heapify(int[] arr, int i, int length) {
        if (i >= length) {
            return;
        }
        int max = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        if (left < length && arr[left] > arr[max]) {
            max = left;
        }
        if (right < length && arr[right] > arr[max]) {
            max = right;
        }
        if (max != i) {
            swap(arr, i, max);
            heapify(arr, max, length);
        }
    }

    private static void swap(int[] arr, int i, int max) {
        int temp = arr[i];
        arr[i] = arr[max];
        arr[max] = temp;
    }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!