堆排序的Java实现、性能分析以及适用场景

1.堆排序的Java实现:

代码如下:

package com.zm.testSort;
/**
 * 堆排序
 * @author zm
 */
public class HeapSort {
    public static void getHeapSort(int[] a) {//堆排序
        int n = a.length;
        if(a == null || n == 1) {
            return;
        }
        buildMaxHeap(a, n);//调用构建最大堆方法,构建一个最大堆
        swap(a, 0, n-1);//交换堆顶元素和堆尾元素,将最大元素置于数组尾端
        for(int len = n-1; len > 1; len--) {//此时需比较的数组长度为n-1,由于此时除了堆顶元素之外,其他元素都符合最大堆,因此只需每次调整堆顶元素
            adjustDown(a, 0, len);//0代表堆顶元素,len代表需比较的数组部分长度
            swap(a, 0, len-1);//交换需比较的数组部分的堆顶元素和堆尾元素
        }

    }
    public static void buildMaxHeap(int[] a, int length) {//构建最大堆
        int k = (length -2)/2;//获取堆尾元素的父节点的索引
        for(; k >=0; k--) {//由该索引开始,从右往左,从下到上,依次调整
            adjustDown(a, k, length);//k表示当前(非叶子节点)父节点的索引
        }
    }

    public static void adjustDown(int[] a, int k, int length) {//调整当前节点与它的所有子节点,构建子最大堆
        int temp = a[k];
        for(int i = 2*k+1; i < length; i = 2*i+1) {//i为父节点的左子节点
            if((i+1)<length) {//如果有右子节点
                if(a[i] < a[i+1]) {//如果右子节点比左子节点大
                    i++;
                }
            }
            if(temp < a[i]) {//如果父节点小于左右子节点中的最大者
                a[k] = a[i];
                k = i;//移到子节点中的大着节点上
            }else{
                break;
            }
        }
        a[k] = temp;
    }
    public static void swap(int[] a, int b, int c) {
        int temp = a[b];
        a[b] = a[c];
        a[c] = temp;
    }

    public static void main(String[] args) {
            int[] a = {3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34, 8, 23, 6, 9};
            getHeapSort(a);
            System.out.print("堆排序:");
            for(int i = 0; i < a.length; i++) {
                System.out.print(a[i] + " ");
            }
    }
}

2.堆排序的性能分析:

时间复杂度:
1. 最好情况:O(nlog2(n))
2. 平均情况:O(nlog2(n))
3. 最坏情况:O(nlog2(n))
空间复杂度:O(1)
稳定性:不稳定(相同元素的相对位置会改变)

3.适用场景

3.1:若n较大,则应采用时间复杂度为O(nlog2(n))的排序方法:快速排序、堆排序或归并排序。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
3.2:优先队列通常用堆排序来实现。

猜你喜欢

转载自blog.csdn.net/zm13007310400/article/details/77418053