【金九银十】笔试通关 + 小学生都能学会的堆排序

news2024/11/26 8:25:21

请在此添加图片描述

算法原理

堆排序是一种基于比较的排序算法,它利用了数据结构中的堆(Heap)。堆是一种特殊的完全二叉树,分为最大堆(Max-Heap)和最小堆(Min-Heap)。在最大堆中,每个父节点的值都大于或等于其子节点的值;在最小堆中,每个父节点的值都小于或等于其子节点的值。

构建最大堆:将给定的无序数组重新调整成一个最大堆。最大堆是堆排序的核心数据结构,它确保了堆顶元素(根节点)是当前堆中的最大值。

排序

  • 将最大堆的根节点(即当前堆中最大值)与堆的最后一个元素交换位置。此时,最大值被移动到数组的末尾,并从堆中移除。
  • 对新的堆顶元素进行堆调整。调整后的堆可能会破坏最大堆的性质,因此需要重新调整堆以恢复最大堆的性质。
  • 重复上述步骤,将堆顶元素移到已排序部分的末尾,直到堆的大小为 1。最终,所有元素将按从小到大的顺序排列。

完成排序:经过上述步骤后,数组中的元素将按照从小到大的顺序排列。

堆排序算法由 J.W.J. Williams 在 1964 年首次提出。他在论文中描述了这一算法的基本概念,并将其称为“堆排序”算法。堆排序的核心思想是通过最大堆的性质来完成排序,这一思想是基于完全二叉树的特性。

堆排序的发明背景与计算机科学早期的发展密切相关。在计算机科学发展的初期,排序算法是一个重要的研究领域。随着计算机应用的普及,如何高效地对大量数据进行排序成为一个实际问题。J.W.J. Williams 的研究为解决这一问题提供了一种新的思路。

堆排序不仅具有良好的时间复杂度(O(n log n)),而且在实际应用中也表现出稳定的性能。这使得堆排序成为计算机科学中一个经典且重要的排序算法。

实例分析

假设我们有一个无序数组 [4, 10, 3, 5, 1],通过堆排序将其排序为 [1, 3, 4, 5, 10]

初始数组[4, 10, 3, 5, 1]

构建最大堆:将 10 放到根节点,堆结构如下:

    10
   /  \
  5    3
 / \
4   1

  • 对堆进行调整后,数组变为 [10, 5, 3, 4, 1]

交换堆顶与末尾元素:交换 10 和 1,得到 [1, 5, 3, 4, 10]。此时最大元素 10 已排好序。

调整剩余部分

- 调整堆结构,得到 `[5, 4, 3, 1, 10]`。
- 再次交换堆顶和末尾,得到 `[1, 4, 3, 5, 10]`。
- 重复上述过程,最终得到 `[1, 3, 4, 5, 10]`。

动态实现

下面是一个简单的示例,演示如何使用 JavaScript 实现堆排序,并通过 HTML 来展示排序的过程。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Heap Sort Visualization</title>
    <style>
        body {
            font-family: 'Roboto', sans-serif;
            background-color: #f4f4f9;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            padding: 0;
        }

        h1 {
            color: #2c3e50;
            margin-bottom: 20px;
            font-weight: 300;
            font-size: 2em;
            text-align: center;
        }

        .array-container {
            display: flex;
            justify-content: center;
            align-items: flex-end;
            width: 90%;
            max-width: 1000px;
            height: 600px;
            border: 1px solid #e1e8eb;
            border-radius: 12px;
            background-color: #ffffff;
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
            padding: 15px;
            box-sizing: border-box;
            overflow: hidden;
        }

        .array-bar {
            width: 40px;
            margin: 0 4px;
            background-color: #3498db;
            border-radius: 8px 8px 0 0;
            transition: all 0.6s ease;
            position: relative;
        }

        .array-bar::after {
            content: attr(data-value);
            position: absolute;
            top: -25px;
            left: 50%;
            transform: translateX(-50%);
            font-size: 16px;
            color: #2c3e50;
            font-weight: bold;
        }

        button {
            padding: 12px 25px;
            margin-top: 30px;
            font-size: 18px;
            color: #ffffff;
            background-color: #3498db;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            transition: background-color 0.4s ease, transform 0.2s ease;
        }

        button:hover {
            background-color: #2980b9;
        }

        button:active {
            background-color: #1c648d;
            transform: scale(0.98);
        }
    </style>
</head>
<body>

<h1>Heap Sort Visualization</h1>
<div class="array-container" id="array-container"></div>
<button onclick="heapSort()">Sort</button>

<script>
    const array = [4, 10, 3, 5, 1];

    function displayArray(arr) {
        const container = document.getElementById('array-container');
        container.innerHTML = '';
        arr.forEach(value => {
            const bar = document.createElement('div');
            bar.style.height = `${value * 50}px`;
            bar.classList.add('array-bar');
            bar.setAttribute('data-value', value); // 显示条形图的数值
            container.appendChild(bar);
        });
    }

    function heapify(arr, length, i) {
        let largest = i;
        let left = 2 * i + 1;
        let right = 2 * i + 2;

        if (left < length && arr[left] > arr[largest]) {
            largest = left;
        }

        if (right < length && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest !== i) {
            [arr[i], arr[largest]] = [arr[largest], arr[i]];
            heapify(arr, length, largest);
        }
    }

    async function heapSort() {
        let length = array.length;

        for (let i = Math.floor(length / 2 - 1); i >= 0; i--) {
            heapify(array, length, i);
        }

        for (let i = length - 1; i >= 0; i--) {
            [array[0], array[i]] = [array[i], array[0]];
            heapify(array, i, 0);
            displayArray(array);
            await new Promise(resolve => setTimeout(resolve, 500)); // 动态显示
        }
    }

    // Initial display
    displayArray(array);
</script>

</body>
</html>

请在此添加图片描述

代码解释

在下面的代码中,我们实现了堆排序算法,并动态展示了排序过程。

const array = [4, 10, 3, 5, 1];

function displayArray(arr) {
    const container = document.getElementById('array-container');
    container.innerHTML = '';
    arr.forEach(value => {
        const bar = document.createElement('div');
        bar.style.height = `${value * 50}px`; // 设置条形图的高度
        bar.classList.add('array-bar');
        bar.setAttribute('data-value', value); // 显示条形图的数值
        container.appendChild(bar);
    });
}

1. displayArray 函数

  • 目的:动态显示数组的当前状态。
  • 参数arr 是需要显示的数组。
  • 操作
    • 清空数组容器 (container.innerHTML = '')。
    • 遍历数组,创建每个元素的条形图 (div)。
    • 设置条形图的高度来表示数组元素的值 (bar.style.height =${value * 50}px`),更高的条形图表示更大的值。
    • 将条形图添加到容器中 (container.appendChild(bar))。
function heapify(arr, length, i) {
    let largest = i;
    let left = 2 * i + 1;
    let right = 2 * i + 2;

    if (left < length && arr[left] > arr[largest]) {
        largest = left;
    }

    if (right < length && arr[right] > arr[largest]) {
        largest = right;
    }

    if (largest !== i) {
        [arr[i], arr[largest]] = [arr[largest], arr[i]];
        heapify(arr, length, largest);
    }
}

2. heapify 函数

  • 目的:将数组调整成一个最大堆,以便在堆排序中能够正确地取出最大值。
  • 参数
    • arr:待调整的数组。
    • length:当前堆的有效大小。
    • i:当前节点的索引。
  • 操作
    • 初始化:假设当前节点是最大的节点 (largest = i)。
    • 比较左子节点:如果左子节点存在且大于当前节点,则更新最大节点为左子节点 (largest = left)。
    • 比较右子节点:如果右子节点存在且大于当前节点,则更新最大节点为右子节点 (largest = right)。
    • 交换:如果最大节点不是当前节点,则交换它们,并递归调用 heapify 以确保堆的性质在交换后仍然保持。
async function heapSort() {
    let length = array.length;

    // 建立最大堆
    for (let i = Math.floor(length / 2 - 1); i >= 0; i--) {
        heapify(array, length, i);
    }

    // 排序
    for (let i = length - 1; i >= 0; i--) {
        [array[0], array[i]] = [array[i], array[0]]; // 交换当前根节点与最后一个节点
        heapify(array, i, 0); // 重新调整堆
        displayArray(array); // 更新显示
        await new Promise(resolve => setTimeout(resolve, 500)); // 等待一段时间,以便用户看到排序过程
    }
}

// 初次显示数组
displayArray(array);

3. heapSort 函数

  • 目的:执行堆排序算法,并动态展示排序过程。
  • 操作
    • 建立最大堆:从最后一个非叶子节点开始,向上调整堆,确保整个数组满足最大堆的性质。
    • 排序过程
      • 交换根节点(最大值)与当前堆的最后一个节点,并减少堆的有效大小 (i)。
      • 重新调整堆以确保堆的性质,并更新显示。
      • 使用 await new Promise(resolve => setTimeout(resolve, 500)) 添加延迟,便于用户观察排序过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单场数字人直播爆量300万,GMV狂增80%,电商人如何玩转数字人直播?

单场直播带货300万&#xff0c;在头部主播那里也许不算什么。但如果告诉你&#xff0c;这是数字人直播做出的成绩&#xff0c;你会惊讶吗&#xff1f; 苏宁借力电商数字人开播&#xff0c;直播时长比以往能增加3倍&#xff0c;GMV增量80%&#xff0c;下单转化57%&#xff0c;不…

通过祖先序列重建辅助工程化UDP-糖基转移酶-文献精读64

Engineering the Substrate Specificity of UDP-Glycosyltransferases for Synthesizing Triterpenoid Glycosides with a Linear Trisaccharide as Aided by Ancestral Sequence Reconstruction 通过祖先序列重建辅助工程化UDP-糖基转移酶的底物特异性&#xff0c;用于合成具…

RWKV-CHN模型部署教程

一、模型介绍 RWKV 语言模型&#xff08;用纯 100%RNN 达到 GPT 能力&#xff0c;甚至更强&#xff09;&#xff0c;该项目旨在通过为您自动化所有事情来消除使用大型语言模型的障碍。您需要的是一个只有几兆字节的轻量级可执行程序。此外&#xff0c;该项目还提供了一个接口兼…

Vue打印网页pdf,并且有按钮调整缩小放大

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

[AutoSar]BSW_Diagnostic_005 RoutineControl service (0x31)介绍

目录 关键词平台说明背景一、请求格式二、sub-function definition三、响应格式四、NRC五、case 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagnostic 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC)autosar版…

录屏工具分享

遇到问题 现在很多录屏工具都是要会员 要么就不清&#xff0c;压缩画质 解决方案 &#xff08;1&#xff09;QQ录屏 QQ录屏缺点就是界面上会有个录屏计时阻挡。没有影响的话可以使用。录几分钟出来也是几百M的容量 &#xff08;2&#xff09;格式工厂 录的视频很清晰&…

打造梦幻AI开发环境:一步步解锁高效配置的魅力

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言&#…

【如何保存Pixso中原型图的图标】

【如何保存Pixso中原型图的图标】 在软件UI设计完成后&#xff0c;设计师需要将设计中的图标导出为开发团队所需的图片文件&#xff0c;以便进行后续开发工作。pixso中原型图的图标到处如下图&#xff0c;按照序号操作流程即可到处图片。

wireshark获取QQ图片

今天随手写下之前做的一个比较有意思的实验&#xff1a;Wireshark抓取qq图片 1.前提 手机和电脑处于同一网络之中&#xff0c;这里我使用了校园网。 接着使用手机向电脑发出图片 2.wireshark流量抓包 先查看好手机的ip地址&#xff0c;随后使用命令&#xff1a;ip.src10.33.X…

MybatisPlus的日常使用

一、基础接口 public interface BaseMapper<T> {/*** 插入一条记录* param entity 实体对象*/int insert(T entity);/*** 根据 ID 删除* param id 主键ID*/int deleteById(Serializable id);/*** 根据 columnMap 条件&#xff0c;删除记录* param columnMap 表字段 map …

Anthropic Message Batches API 满足批量处理大量请求

现在开发的系统有大量知识汇总统计、跑批处理需求的同学可以尝试一下&#xff0c;看看能不能解决自己目前的问题~~ 可能是一个解决方案 Anthropic 推出的 Message Batches API &#xff0c;专门用于帮助开发者批量处理大量请求。它的主要目的是通过一次性处理大量非实时任务&a…

Linux工具的使用——【gcc/g++的使用】【make/Makefile的使用】【如何让普通用户使用sudo】

目录 Linux工具的使用-021.如何让普通用户使用sudo1.1为什么无法使用sudo1.2解决步骤1.3验证 2.编译器gcc/g的使用2.1预处理2.2编译2.3汇编2.4链接2.5函数库2.5.1静态库与动态库2.5.1.1动态链接2.5.1.2静态链接 2.6gcc的默认链接方式2.7gcc的静态链接2.8g的使用2.8.1g的静态链接…

Apache Flink Dashboard

1、Overview Apache Flink Web Dashboardhttp://110.40.130.231:8081/#/overview 这张图片显示的是Apache Flink的Web UI界面&#xff0c;其中包含了以下几个部分&#xff1a; Available Task Slots: 显示当前可用的任务槽位数量。任务槽位是指Flink集群中可用于运行任务的资…

【华为HCIP实战课程十】OSPF网络DR和BDR实战讲解,网络工程师

一、DR与BDR的基础介绍 点到点同步LSA成本小 多点接入网络同步LSA成本大,需要DR/BDR 由于MA网络中,任意两台路由器都需要传递路由信息,网络中有n台路由器,则需要建立n*(n-1)/2个邻接关系。任何一台路由器的路由变化都会导致多次传递,浪费了带宽资源,DR和BDR应运而生!…

大数据存储计算平台EasyMR:多集群统一管理助力企业高效运维

随着全球企业进入数字化转型的快车道&#xff0c;数据已成为企业运营、决策和增长的核心驱动力。为了处理海量数据&#xff0c;同时应对数据处理的复杂性和确保系统的高可用性&#xff0c;企业往往选择部署多个Hadoop集群&#xff0c;这样的策略可以将生产环境、测试环境和灾备…

分布式 ID

背景 在复杂分布式系统中&#xff0c;往往需要对大量的数据和消息进行唯一标识。随着数据日渐增长&#xff0c;对数据分库分表后也需要有一个唯一ID来标识一条数据或消息&#xff0c;数据库的自增 ID 显然不能满足需求&#xff1b;此时一个能够生成全局唯一 ID 的系统是非常必…

电商选品/跟卖| 亚马逊卖家精灵爬虫

卖家精灵(SellerSprite)基于大数据和人工智能技术,精准查询每个产品的销量、关键词、自然搜索数据,为亚马逊跨境卖家提供一站式选品、市场分析、关键词优化、产品监控等, 基于买家精灵跟卖,可谓事半功倍, 如何利用买家精灵, 快速获取跟卖信息. from extensions.basic_exte…

Java基础知识——String篇

一、String 1、是什么 String 是 Java 中用于表示字符串的类。Java 中的字符串是不可变的&#xff0c;也就是说一旦创建&#xff0c;字符串的内容无法更改。 2、如何构造 &#xff08;1&#xff09;无参数构造方法&#xff1a; String str new String(); //创建一个空字符…

毕业设计项目-基于Spring Boot开发的古诗词管理系统

项目简介 这是一个基于Spring Boot开发的古诗词管理系统&#xff0c;旨在为用户提供在线古诗词交流平台。系统分为用户和管理员两个角色&#xff0c;各自拥有不同的功能和权限。该系统提供了以下功能&#xff1a; 用户功能&#xff1a; 登录和注册功能&#xff0c;确保用户身…

json格式的post请求目前不行, 要换成form表单形式的post请求怎么改

问: 下面是我的代码 export function fetchDeleteList<T>(agentSessionId: string) {return post<T>({url: http://192.168.0.116:8089/pipe-ics/agent/delete,method: post,data: { agentSessionId },}) } 目前是json格式的post请求, 目前不行, 要换成form表单…