堆排序

来源:互联网 发布:mac怎么删除flash 编辑:程序博客网 时间:2024/06/14 18:57

堆排序的核心是创建最大堆,然后对堆进行调整。整个算法的实现比较简单,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//调整堆的分支结构--核心方法,注意这里的对于heapsize参数的设计,有的人会觉得这里完全可以通过heap进行计算求得,
//为什么一定要在参数中出现呢?我们看到后面就知道了。
public static void maxHeap(int[] heap, int heapsize, int index) {
    int left = left(index);
    int right = right(index);
    int largest = index;
    //得到最大节点的下标(index)
    if (left < heapsize && heap[left] > heap[index]) {
        largest = left;
    }
    if (right < heapsize && heap[right] > heap[largest]) {
        largest = right;
    }
    if (index != largest) {
        swap(heap, index, largest);
        //继续向下调整堆,直到符合最大堆的要求
        maxHeap(heap, heapsize, largest);
    }
}
 
public static void buildMaxHeap(int[] array) {
    if (array == null || array.length < 1) {
        return;
    }
    for (int i = array.length / 2; i >= 0; i--) {
        //构建最大堆。。。只构建到一半是因为后面的都被动调整过l,不需要再次构建
        maxHeap(array, array.length, i);
    }
}
 
public static void heapSort(int[] array) {
    if (array == null || array.length <= 1) {
        return;
    }
    buildMaxHeap(array);
    //此时已经建立好最大堆了
    for (int i = array.length - 1; i >= 1; i--) {
        swap(array, 0, i);
        //因为最大堆建好之后要进行一步交换操作,这是如果把需要排序的数组长度作为参数传进去的话更利于调整控制。
        //这也就是为什么在开始的时候会有参数设置这个疑问。
        maxHeap(array, i, 0);
    }
}
 
public static void swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}
 
public static int left(int i) {
    return 2 * i;
}
 
public static int right(int i) {
    return 2 * i + 1;
}

最优时间复杂度:O(nlog(n))


平均时间复杂度:O(nlog(n))


最坏时间复杂度:O(nlog(n))


平均空间复杂度:O(1)

堆排序的时候也不停地有元素交换操作,所以堆排是不稳定的。

0 0
原创粉丝点击