算法学习与代码实现5——堆排序

算法学习与代码实现5——堆排序

堆排序的思想当年看《算法导论》看了好几遍也没理解,现在算是明白了。

算法思路

堆排序借助的是堆这个数据结构。堆首先是个完全二叉树,可以用数组表示。下面一张《算法导论》中的插图形象的表示了二叉堆在数组中的表示:

这里写图片描述

而最大堆又满足一个额外的条件:

A[PARENT(i)] ≥A[i]

这样,在堆排序中,我们需要首先将一个数组变成最大堆,然后将数组的第一个数和最后一个数互换,再将最后一个数从堆中排除,剩下的数再次进行这个过程,知道所有的数都从数组中派出,被排除的数就组成了一个排好序的序列。

算法性能

稳定性:不稳定

时间复杂度: O(nlogn)

空间复杂度:O(1)

伪代码

堆排序有两个辅助函数,一个是保持堆的性质,一个是建立最大堆。

保持堆的性质

MAX-HEAPIFY(A, i)
l <- LEFT(i)
r <- RIGHT(i)
if l ≤ heap-size[A] and A[l] > A[i]
    then largest <- l
    else largest <- i
if r ≤ heap-size[A] and A[r] > A[largest]
    then largest <- r
if largest ≠ i
    then exchange A[i] <-> A[largest]
         MAX-HEAPIFY(A, largest)

建立最大堆

BUILD-MAX-HEAP(A)
heap-size[A] <- length[A]
for i <- length[A]/2向下取整 downto 1
    do MAX-HEAPIFY(A, i)

堆排序

HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i <- length[A] downto 2
    do exchange A[1] <->A[i]
       heap-size[A] <- heap-size[A] - 1
       MAX-HEAPIFY(A, 1)

C语言实现

堆排序对数组序号的使用比较多,因为它完全就是使用数组的需要来表示数组中的元素在堆中的位置。相互关系也要用到序号。而《算法导论》中的介绍都是从序号1开始的,c语言实现中为了避免不必要的麻烦,也从序号1开始。

保持堆的性质

#define LEFT(i)     (2 * i)
#define RIGHT(i)    (2 * i + 1)
void max_heapify(int * array, int node, int array_size){
    int heap_size = array_size;
    int l = LEFT(node);
    int r = RIGHT(node);
    int largest;
    if (l <= heap_size && array[l] > array[node]) {
        largest = l;
    }
    else {
        largest = node;
    }
    if (r <= heap_size && array[r] > array[largest]) {
        largest = r;
    }
    if (largest != node) {
        int tmp = array[node];
        array[node] = array[largest];
        array[largest] = tmp;
    }
    if (largest != node)
        max_heapify(array, largest, array_size);
}

建立最大堆

void build_max_heap(int * array, int array_size){
    for (int i = array_size/2; i >= 1; i--) {
        max_heapify(array, i, array_size);
    }
}

堆排序

void heap_sort(int * array, int array_size){
    build_max_heap(array, array_size);
    int heap_size = array_size;
    for (int i = array_size; i >= 2; i--) {
        int tmp = array[1];
        array[1] = array[i];
        array[i] = tmp;
        heap_size -= 1;
        max_heapify(array, 1, heap_size);
    }
}

本文代码托管于:
https://github.com/haoranzeus/algorithms_study

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值