排序七 堆排序

堆排序(Heap Sort)

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。—百度百科

时间复杂度:最好 O(n)=O(n);平均O(n)=O(nlogn);最差O(n)=O(nlogn)
空间复杂度:O(n)=O(1)
稳定性:    不稳定

堆(Heap)

:    顺序储存的完全二叉树,其每个结点均小于等于或大于等于其子节点。

小根堆:每个结点元素的值都小于等于其子节点元素的值的堆。
        S[i]<=S[2*i+1] && S[i]<=S[2*i+2]

大根堆:每个结点元素的值都大于等于其子节点元素的值的堆。
        S[i]>=S[2*i+1] && S[i]>=S[2*i+2]

堆顶:    序列中第一个元素S[0],为序列中最小值(小根堆)或最大值(大根堆)。

左子节点:S[2*i+1]
右子节点:S[2*i+2]
父节点:  S[(i-1)/2]
如下图,有一个数组S[9,6,7,3,1,4]即为一个大根堆。其堆顶为S[0]=9。
Heap

算法描述

HeapSort
wiki

建堆算法

从最后一个非叶节点开始上调整,将最较大的值往上顶。
例:[9,1,5,3,8,7,2,4,6,0]
HeapAdjust

排序算法

  1. 将待排序序列调整大根堆。
  2. 交换堆顶和末尾元素,将堆顶元素(即最大值)抛出,将剩余序列继续步骤1,直到剩余序列大小为零。
    例:[9,1,5,3,8,7,2,4,6,0]
    HeapSort

示例代码

代码参考自Chimomo

/// <summary>  
/// 堆排序  C#
/// </summary>  
public static void HeapSort(int[] S){
    // 由底向上建 大顶堆
    // 由完全二叉树的性质可知,叶子结点是从index=S.Length/2开始,
    // 所以从index=(S.Length/2)-1结点开始由底向上进行大根堆的调整。  
    for (int i = (S.Length / 2) - 1; i >= 0; i--) {
        HeapAdjust(S, i, S.Length);
    }
    // 每一遍循环将堆顶元素(即最大值)抛出到数组末尾,然后堆大小减一,从新建堆
    for (int i = S.Length - 1; i > 0; i--) {
         S.Swap(0, i);        // 将堆顶元素和最后一个元素交换
         HeapAdjust(S, 0, i); // 剩余区域建堆
    }
}
/// <summary>  
/// 将指定的结点调整为堆 
/// </summary>  
private static void HeapAdjust(int[] S, int i, int heapSize){
    int left = (2 * i) + 1;  // 左子结点索引   
    int right = left + 1;    // 右子结点索引   
    int large = i;           // 存放大的结点值的索引 

    // 比较左子结点
    if (left < heapSize && S[left] > S[large]) {
        large = left;
    }
    // 比较右子结点
    if (right < heapSize && S[right] > S[large]) {
        large = right;
    }
    // 如有子结点大于自身就交换,使大的元素上移
    // 并递归该子节点,以保证堆的性质
    if (i != large) {
        S.Swap(i, large);
        HeapAdjust(S, large, heapSize);
    }
}
def heap_sort(s):  #Python
    for i in range(len(s)//2-1, -1, -1):
        heap_adjust(s, i, len(s))

    for i in range(len(s)-1, 0, -1):
        s[0], s[i] = s[i], s[0]
        heap_adjust(s, 0, i)

def heap_adjust(s, i, size):
    left = 2 * i + 1
    right = left + 1
    large = i

    if left < size and s[left] > s[large]:
        large = left
    if right < size and s[right] > s[large]:
        large = right

    if i != large:
        s[i], s[large] = s[large], s[i]
        heap_adjust(s, large, size)

文中若有什么错误,欢迎留言指正。

转载请保留出处:http://blog.csdn.net/x1060549/article/details/78792704

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值