堆排序——排序算法

文章目录

  • 前言
  • 一、什么是堆排序?
  • 二、算法描述
  • 三、JS代码实现
  • 总结


前言

  不知不觉已经实习了2个月了,还记得刚进公司还是个小白,现在已经进化为大白了(哈哈哈),其实多多少少还是有进步的,毕竟还是参与了开发流程,虽然小公司并没有那么正规的流程,但是多少还是让我这个大四老g学到了不少东西,在公司这两个月,一边学习一边写代码,每次完成一个需求都会进步不少,重复迭代,对这一块业务也算能处理了。不扯这么多了,如果有机会尽量还是进大一点的公司吧,哈哈哈!今天整理一下堆排序,老实说这个堆排序在学校的老师是讲过的,但是当时对数据结构并不重视,现在非常后悔,所以这次花了两天看了一下这个堆排序总算理解了。


一、什么是堆排序?

  堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

二、算法描述

  在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。
算法步骤:

  1. 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  2. 创建最大堆(Build Max Heap):将堆中的所有数据重新排序
  3. 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

算法复杂度:

  • 时间复杂度:
    • 最好:O(nlog2n)
    • 最坏:O(nlog2n)
    • 平均: O(nlog2n)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

三、JS代码实现

  下面是JS代码示例,可以在node环境运行代码,查看结果。这里我使用了ES6的类的写法,不懂的可以百度一下,其实这里借鉴别人的代码,需要设置一个全局变量len,所以我想办法改成了一个类来实现,我觉得可能复杂了,能看懂就可以其实也不复杂。

代码如下(示例):

class HeapSort {
    constructor(arr) {
        this.ary = arr;
        this.len = arr.length;
    }

    heapfiy(arr, i) { //堆调整
        let left = 2 * i + 1, right = 2 * i + 2, largest = i; //数组映射到树上的子结点
        if (left < this.len && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < this.len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest !== i) { //如果子结点比父结点大就进行交换
            [arr[largest], arr[i]] = [arr[i], arr[largest]];
            this.heapfiy(arr, largest); //递归子结点,继续交换最大值
        }
    }
    /*
    下面是堆 序号 对应数组
            0
       1          2
     3   4     5     6
    7 8 9 10 11 12 13 14 
    */
    buildMaxHeap(arr) { //建立大顶堆
        for (let i = parseInt(this.len / 2); i >= 0; i--) { // 自下而上的进行交换
            this.heapfiy(arr, i);
        }
    }

    sort() {
        let arr = this.ary;
        this.buildMaxHeap(arr);
        for (let i = this.len - 1; i > 0; i--) {
            [arr[0], arr[i]] = [arr[i], arr[0]]; //每个最大数(堆顶数)和末尾数交换(this.len位置)
            this.len--; //已排序数不参与堆排序
            this.heapfiy(arr, 0); //剩余堆重排找最大数
        }
    }
}
//测试堆排序
let arr = [9, 8, 2, 5, 1, 3, 6, 4, 7, 0];
let heapSort = new HeapSort(arr);
heapSort.sort();
console.log(arr);

运行结果图:
堆排序——排序算法_第1张图片


总结

  十大排序算法已经写到第七篇了,虽然行文有点水,但是每次代码我都是反复运行测试理解透彻后才来写,可能文笔不佳,让大家读了可能有点混乱,推荐大家看看十大经典排序算法我这里的十大排序算法全是参考这位大佬的,而且有相应的排序算法图解,绝对是经典排序算法里面讲的最透彻的一篇了。给自己定了一个每周一篇博客的flag,所以才决定复盘这些,也相当于是记笔记吧,我想只有不断的记录自己的学习才能不断的提高。坚持一些事不一定能有所回报,但是坚持下来一定很酷。

—— 2021.1.31 新的一年一定要加油出质量更高的博客,加油!

今日份励志名言:

“道阻且长,行则将至。”

你可能感兴趣的:(算法,算法,排序算法,数据结构)