堆排序

【0】README

0.1) 本文总结于 数据结构与算法分析,但源代码均为原创;旨在理清堆排序的具体步骤;
0.2)这里用到了 到 二叉堆(优先队列)的下滤操作(不过它是 percolateDownFromZero版本), 二叉堆(优先队列) details ,参见 http://blog.csdn.net/pacosonswjtu/article/details/49498255


【1】堆排序相关

1.1)堆排序定义:优先队列可以用于 花费 O(N logN)时间的排序。基于该想法的算法叫做堆排序;
1.2)在实践中: 堆排序慢于 使用 Sedgewick 增量序列的希尔排序; 希尔排序详情,参见
http://blog.csdn.net/pacosonswjtu/article/details/49660799


【2】堆排序的基本方法

3.0)我们执行 N 次 deleteMin 操作,按照顺序, 最小的元素先离开该堆, 通过将这些元素记录到第二个数组然后再将数组copy 回来, 我们得到N个元素的排序, 由于每个deleteMin 花费时间 O(logN), 因此总的运行时间是 O(NlogN);
3.1)上述基本方法的问题: 在于它使用了一个附加的数组, 因此, 存储需求增加了一倍, 在某些实际问题中,这是不可能的。注意,将第二个数组copy 回第一个数组的额外时间消耗只是O(N), 这不可能显著影响运行时间, 这个问题是空间复杂度的问题;
3.2)上述基本方法的解决方法:在每次deleteMin之后, 堆缩小了1, 因此,位于堆中最后的单元可以用来存放 刚刚删去的元素;
3.3)使用这种策略, 在最后一次 deleteMin之后, 该数组将以递减的顺序包含这些元素。如果我们想要这些元素排成递增的顺序, 那么我们可以改变序的特性使得父亲的关键字的值大于儿子的关键字的值;(不过,我的源代码,采用的是小根堆, 也即,堆排序完后,元素排成了降序的形式)


【3】源代码+打印结果

3.1)download source code :
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter7/p170_heapSort.c
3.2)source code at a glance :

#include <stdio.h>
#define ElementType int

void swap(ElementType *x, ElementType *y)
{
    ElementType temp;

    temp = *x;
    *x = *y;
    *y = temp;
}

// get the left child of node under index with startup zero
int leftChildFromZero(int index)
{
    return index * 2 + 1;
}

 // percolating down the element when its value is greater than children (minimal heap)
 //Attention: all of bh->elements starts from index 0
 void percolateDownFromZero(int index, ElementType data[], int size)
 {      
    ElementType temp;
    int child;      

    for(temp = data[index]; leftChildFromZero(index) < size; index = child)
    {
        child = leftChildFromZero(index);
        if(child < size - 1 && data[child] > data[child+1])
            child++;
        if(temp > data[child])
            data[index] = data[child];
        else
            break;
    }
    data[index] = temp;
 }

// we adopt ascending order to execute shellSorting operation
void heapSort(ElementType data[], int size)
{       
    int i;

    for(i = size / 2; i >= 0; i--) // building the heap by percolating down
        percolateDownFromZero(i, data, size);            
    for(i = size - 1; i > 0; i--) // delete the minimum element
    {
        swap(&data[0], &data[i]); // switch the minimal also the element with index 0 with the final element in the minimum heap
        percolateDownFromZero(0, data, i);
    }
} 

void printBinaryHeapFromZero(ElementType data[], int size)
{
    int i;

    for(i = 0; i < size; i++)
    {
        printf("\n\t index[%d] = ", i);
        if(i < size)
            printf("%d", data[i]);
        else
            printf("NULL");
    }
    printf("\n");
} 

int main()
{ 
    int size;
    int data[] = {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130};

    printf("\n\t=== test for building heap with {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130} ===\n"); 
    size = 15;

    printf("\n\t=== before executing heap sorting ===\n");  
    printBinaryHeapFromZero(data, size);    
    heapSort(data, size);   
    printf("\n\t=== after executing heap sorting ===\n");       
    printBinaryHeapFromZero(data, size);

    return 0;
}

3.3)打印结果:
这里写图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值