【排序算法】二叉树的实际应用堆排序

简介: 【排序算法】二叉树的实际应用堆排序

堆排序

堆排序基本介绍

堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复 杂度均为 O(nlogn),它也是不稳定排序。

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有 要求结点的左孩子的值和右孩子的值的大小关系。

每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆


大顶堆

2.png


小顶堆

3.png


堆排序基本思想

将待排序序列构造成一个大顶堆

此时,整个序列的最大值就是堆顶的根节点。

将其与末尾元素进行交换,此时末尾就为最大值。

然后将剩余 n-1 个元素重新构造成一个堆,这样会得到 n 个元素的次小值。如此反复执行,便能得到一个有序序列了。

可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.


堆排序步骤图解说明

步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。 原始的数组 [4, 6, 8, 5, 9]

假设给定无序序列结构如下

4.png



此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点


arr.length/2-1=5/2-1=1,也就是下面的 6 结点),从左至右,从下至上进行调整。

5.png



找到第二个非叶节点 4,由于[4,9,8]中 9 元素最大,4 和 9 交换。

6.png



这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中 6 最大,交换 4 和 6。

7.png



此时,我们就将一个无序序列构造成了一个大顶堆。


步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换.


得到第二大元素。如此反复进行交换、重建、交换。


.将堆顶元素 9 和末尾元素 4 进行交换

8.png



重新调整结构,使其继续满足堆定义

9.png



再将堆顶元素 8 与末尾元素 5 进行交换,得到第二大元素 8

10.png



后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序

11.png

12.png

总结下堆排序的基本思路:

将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤, 直到整个序列有序.


代码实现

要求:给你一个数组 {4,6,8,5,9} , 要求使用堆排序法,将数组升序排序。


堆排序不是很好理解,老师通过 Debug 帮助大家理解堆排序

堆排序的速度非常快,在我的机器上 8 百万数据 3 秒左右。O(nlogn)

package com.hyc.DataStructure.tree;


package com.hyc.DataStructure.tree;
/**
 * @projectName: DataStructure
 * @package: com.hyc.DataStructure.tree
 * @className: HeapSort
 * @author: 冷环渊 doomwatcher
 * @description: TODO
 * @date: 2022/2/6 23:52
 * @version: 1.0
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] test = new int[8000000];
        //测试数据
        for (int i = 0; i < 8000000; i++) {
            test[i] = (int) (Math.random() * 800000);
        }
        long time = System.currentTimeMillis();
        heapsort(test);
        long end = System.currentTimeMillis();
        long t = ((end - time) / 1000);
        System.out.println("一共用时 " + t + "秒");
        int arr[] = {4, 6, 8, 5, 9};
    }
    public static void heapsort(int[] arr) {
        int temp = 0;
        //按照 大顶堆的方式调整堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        /*将最大元素和末尾元素交换,将最大元素放入数组末尾
         *重新调整结构,满足堆的定义
         * */
        for (int j = arr.length - 1; j > 0; j--) {
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr, 0, j);
        }
        //System.out.println("排序后的数组是 = " + Arrays.toString(arr));
    }
    /**
     * @author 冷环渊 Doomwatcher
     * @context:
     * 大顶堆交换思路, 判断左右节点大小,之后判断左右节点的比对结果,与父节点判断,将最大值交还给父节点
     * @date: 2022/2/6 23:54
     * @param arr 存放需要将交换节点的数组
     * @param i   需要做调整的父节点索引
     * @param length 有多少节点需要调整
     * @return: void
     */
    public static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];
        //   开始调整
        /* 说明
         * k =i*2+1按照之前线索查找树的公式,找出左子树的节点位置
         * */
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            //判断条件 k(节点索引)首先不能大于我们要遍历的结点索引总数,之后判断左右节点的大小,交换
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            //找出最大的子节点,与父节点的值比对,
            if (arr[k] > temp) {
                //将较大的值放入到父节点
                arr[i] = arr[k];
                i = k; //i指向k , 继续循环比较
            } else {
                break;
            }
        }
        //    for 循环结束之后 我们i已经是父节点以及最大值的索引了
        // 将 temp 调整到最后得位置
        arr[i] = temp;
    }
}


相关文章
|
2天前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
29 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
2天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
34 5
|
2天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
28 0
|
28天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
27天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
44 1
|
27天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
60 1
|
1月前
|
机器学习/深度学习 监控 算法
基于反光衣和检测算法的应用探索
本文探讨了利用机器学习和计算机视觉技术进行反光衣检测的方法,涵盖图像预处理、目标检测与分类、特征提取等关键技术。通过YOLOv5等模型的训练与优化,展示了实现高效反光衣识别的完整流程,旨在提升智能检测系统的性能,应用于交通安全、工地监控等领域。
|
28天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法及应用
探索人工智能中的强化学习:原理、算法及应用
|
2天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
108 80
|
21天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。