利用typescript实现堆排序

本文主要讲解堆排序的原理以及代码实现,要理解堆排序,首先需要了解二叉树,下面我们逐步展开

  1. 树是一种数据结构
  2. 树是由有限个节点(可以理解位一个数据)组成的集合
  3. 树的每个节点最多只能有一个父节点,可以有多个子节点
    依据这三条,可以将树画成图,如图所示
    树的图片
    因其图像就像一棵倒挂的树,所以称为树

二叉树

任意节点最多只有2个子节点的树就是二叉树,上面的图形就不是一棵二叉树
以下就是一棵二叉树
二叉树的图片

完全二叉树

来自百度百科的定义如下:

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

如何理解?
从以数组表示二叉树的结构上看,数组内部没有空洞
从图形上看子节点填充按照从左往右的方式排布

堆严格意义上讲叫二叉堆,因为它可以看做一棵近似的完全二叉树

最大堆

一棵完全二叉树,任何节点,都满足左子节点和右子节点的值都小于该节点的值
堆的图片
如上图所示,取任意一个节点,例如15这个节点,既大于左子节点10,又大于右子节点3,而且其他节点也是满足这种关系的,所以这就可以称为最大堆。

堆排序实现原理

堆排序是基于最大堆实现的,首先先建一个最大堆,那么第一个元素就是所有元素里最大的值,将这个值,与最后一个值交换,这时候最大堆性质没法保持,那么为了保持最大堆,第一个值逐级下沉,即分别与左右子节点进行比较,直至再次保持为最大堆。接着将第一个值与倒数第二个值交换,继续保持最大堆,以此类推。
代码实现如下

export function maxHeapSort<T>(maxHeap: T[], compFunc: (A: T, B: T) => number) {
    let heapSize: number = 0;
    function buildHeap() {
        heapSize = maxHeap.length;
        for(let num = (heapSize - 1) >> 1, i = num; i >= 0; i--) {
            maxHeapify(i);
        }
    }
    
    function left(idx: number) {
        return (idx << 1) + 1;
    }

    function right(idx: number) {
        return (idx << 1) + 2;
    }

    function parent(idx: number) {
        return (idx - 1) >> 1;
    }

    function swap(idx1: number, idx2: number) {
        let tmp = maxHeap[idx1];
        maxHeap[idx1] = maxHeap[idx2];
        maxHeap[idx2] = tmp;
    }

    function maxHeapify(idx: number) {
        let leftIdx = left(idx);
        let largestIdx: number;
        if(leftIdx < heapSize && compFunc(maxHeap[idx], maxHeap[leftIdx]) < 0) 
            largestIdx = leftIdx;
        else
            largestIdx = idx;
        let rightIdx = right(idx);
        if(rightIdx < heapSize && compFunc(maxHeap[largestIdx], maxHeap[rightIdx]) < 0)
            largestIdx = rightIdx;
        if(largestIdx != idx) {
            swap(largestIdx, idx);
            maxHeapify(largestIdx);
        }
        
    }

    buildHeap();
    for(let i = maxHeap.length - 1; i > 0; i--) {
        swap(0, i);
        heapSize--;
        maxHeapify(0);
    }
    return maxHeap;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬季的诅咒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值