当前位置: 首页 > news >正文

分治与减治算法实验: 排序中减治法的程序设计

目录

前言

实验内容

实验目的

实验分析

实验过程

流程演示

写出伪代码

实验代码

代码详解

运行结果

总结


前言

本文介绍了算法实验排序中减治法的程序设计。减治法是一种常用的算法设计技术,它通过减少问题的规模来求解问题。减治法可以应用于排序问题,例如插入排序、选择排序和快速排序等。本文将分析这些排序算法的原理、实现和性能,并给出相应的程序代码和测试结果。

本文中使用的语言是C语言,使用的工具是devc++

实验内容

给出一个记录序列,用堆排序的方法将其进行升序排列,输出结果,输出时要求有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度。

实验目的

(1)掌握堆的有关概念;

(2)掌握堆排序的基本思想和其算法的实现过程;

(3)熟练掌握筛选算法的实现过程;

(4)在掌握的基础上编程实现堆排序的具体实现过程。

实验分析

这个题目要求使用堆排序的方法将一个记录序列进行升序排列,并输出结果和文字说明。需要选择一种编程语言来实现堆排序算法,并分析其算法复杂度。这个题目考察了对堆排序算法的理解和应用能力,以及你对编程语言的掌握程度和代码风格的规范性。需要注意以下几点:

  • 堆排序算法是一种基于二叉堆结构的排序方法,它利用了二叉堆的性质,即堆顶元素是最大或最小值,来不断地选出序列中的最大或最小值,并将其放在正确的位置。它分为两个步骤:构建堆和调整堆。构建堆是从最后一个非叶子节点开始,自下而上地调整每个节点,使其满足大顶堆或小顶堆的性质。调整堆是从最后一个元素开始,将堆顶元素与末尾元素交换,然后调整剩余的元素为新的堆,重复这个过程直到只剩一个元素。
  • 堆排序算法的时间复杂度为O(nlogn),空间复杂度为O(1)。它是一种原地排序算法,不需要额外的空间来存储数据。它的时间复杂度是由构建堆和调整堆的次数决定的,每次构建或调整堆都需要O(logn)的时间,而总共需要进行n次构建或调整,所以总的时间复杂度为O(nlogn)。它的空间复杂度是由交换元素所需的辅助空间决定的,每次交换只需要一个临时变量来存储数据,所以总的空间复杂度为O(1)。

实验过程

流程演示

  1. 首先,我们从最后一个非叶子节点开始,自下而上构建大顶堆。最后一个非叶子节点的索引是(n/2-1),其中n是序列的长度。在这个例子中,n=9,所以最后一个非叶子节点的索引是3,对应的元素是6。我们从这个节点开始,依次向上调整每个节点,使其满足大顶堆的性质。调整的过程是:比较当前节点和它的左右孩子,如果当前节点小于它的左右孩子中的任何一个,就交换它们,并递归地调整被交换的子树。调整后的结果如下:
        9/   \8     7/ \   / \6   5 4   3/ \2   1
  1. 然后,我们将堆顶元素与末尾元素交换,即将9和1交换,这样我们就得到了序列中的最大值,并将其放在了正确的位置。交换后,我们将剩余的元素(除了最后一个)看作一个新的堆,并对其进行调整,使其满足大顶堆的性质。调整后的结果如下:
        8/   \6     7/ \   / \2   5 4   3/
1
  1. 接着,我们重复上面的步骤,将堆顶元素与末尾元素交换,即将8和2交换,这样我们就得到了序列中的第二大值,并将其放在了正确的位置。交换后,我们将剩余的元素(除了最后两个)看作一个新的堆,并对其进行调整,使其满足大顶堆的性质。调整后的结果如下:
        7/   \6     4/ \   /1   5 3/
2
  1. 我们继续重复上面的步骤,直到只剩一个元素为止。每次交换和调整后,我们都会得到序列中的一个最大值,并将其放在了正确的位置。最终,我们得到了升序排列的序列[1, 2, 3, 4, 5, 6, 7, 8, 9]

写出伪代码

//定义一个交换函数,接受一个数组和两个索引作为参数,交换这两个索引对应的元素
swap(arr, i, j):temp <- arr[i]arr[i] <- arr[j]arr[j] <- temp//定义一个调整函数,接受一个数组,一个数组的长度,和一个需要调整的节点的索引作为参数,调整该节点和它的子树,使其满足大顶堆的性质
heapify(arr, n, i):largest <- i //假设当前节点为最大值left <- 2 * i + 1 //左孩子的索引right <- 2 * i + 2 //右孩子的索引//如果左孩子存在且大于当前节点,更新最大值的索引if left < n and arr[left] > arr[largest]:largest <- left//如果右孩子存在且大于当前节点,更新最大值的索引if right < n and arr[right] > arr[largest]:largest <- right//如果最大值不是当前节点,交换它们,并递归地调整被交换的子树if largest != i:swap(arr, i, largest)heapify(arr, n, largest)//定义一个堆排序函数,接受一个数组和一个数组的长度作为参数,对该数组进行升序排列
heapSort(arr, n)://从最后一个非叶子节点开始,自下而上地构建大顶堆for i from n / 2 - 1 to 0:heapify(arr, n, i)//从最后一个元素开始,将堆顶元素与末尾元素交换,然后调整剩余的元素为新的大顶堆,重复这个过程直到只剩一个元素for i from n - 1 to 1:swap(arr, 0, i)heapify(arr, i, 0)//定义一个打印函数,接受一个数组和一个数组的长度作为参数,打印该数组中的每个元素
printArray(arr, n):for i from 0 to n - 1:print arr[i] and a spaceprint a newline//测试代码
main()://通过键盘输入序列的长度和元素print "请输入序列的长度:"read n //读取序列的长度print "请输入序列的元素:"arr <- an array of size n //动态分配内存空间存储序列for i from 0 to n - 1:read arr[i] //读取每个元素//输出原始序列print "原始序列:"printArray(arr, n)//使用堆排序算法对序列进行升序排列heapSort(arr, n)//输出排序结果print "排序结果:"printArray(arr, n)

实验代码

#include <stdio.h>
#include <stdlib.h>//交换数组中的两个元素
void swap(int arr[], int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}//调整数组中的元素,使其满足大顶堆的性质
void heapify(int arr[], int n, int i) {int largest = i; //假设当前节点为最大值int left = 2 * i + 1; //左孩子的索引int right = 2 * i + 2; //右孩子的索引//如果左孩子存在且大于当前节点,更新最大值的索引if (left < n && arr[left] > arr[largest]) {largest = left;}//如果右孩子存在且大于当前节点,更新最大值的索引if (right < n && arr[right] > arr[largest]) {largest = right;}//如果最大值不是当前节点,交换它们,并递归调整被交换的子树if (largest != i) {swap(arr, i, largest);heapify(arr, n, largest);}
}//堆排序算法
void heapSort(int arr[], int n) {//从最后一个非叶子节点开始,自下而上构建大顶堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}//从最后一个元素开始,将堆顶元素与末尾元素交换,然后调整剩余的元素为新的大顶堆,重复这个过程直到只剩一个元素for (int i = n - 1; i > 0; i--) {swap(arr, 0, i);heapify(arr, i, 0);}
}//打印数组
void printArray(int arr[], int n) {for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");
}//测试代码
int main() {//通过键盘输入序列的长度和元素printf("请输入序列的长度:\n");int n;scanf("%d", &n); //读取序列的长度printf("请输入序列的元素:\n");int *arr = (int *)malloc(sizeof(int) * n); //动态分配内存空间存储序列for (int i = 0; i < n; i++) {scanf("%d", &arr[i]); //读取每个元素}//输出原始序列printf("原始序列:\n");printArray(arr, n);//使用堆排序算法对序列进行升序排列heapSort(arr, n);//输出排序结果printf("排序结果:\n");printArray(arr, n);//释放内存空间free(arr);return 0;
}

代码详解

代码分为以下几个部分:

  • 交换数组中的两个元素的函数swap,它接受一个数组和两个索引作为参数,然后将这两个索引对应的元素互换位置。
  • 调整数组中的元素,使其满足大顶堆的性质的函数heapify,它接受一个数组,一个数组的长度,和一个需要调整的节点的索引作为参数。它首先假设当前节点为最大值,然后比较它和它的左右孩子,如果左右孩子中有比它大的,就更新最大值的索引。如果最大值不是当前节点,就交换它们,并递归地调整被交换的子树。
  • 堆排序算法的函数heapSort,它接受一个数组和一个数组的长度作为参数。它首先从最后一个非叶子节点开始,自下而上构建大顶堆。然后从最后一个元素开始,将堆顶元素与末尾元素交换,然后调整剩余的元素为新的大顶堆,重复这个过程直到只剩一个元素。
  • 打印数组的函数printArray,它接受一个数组和一个数组的长度作为参数。它遍历数组中的每个元素,并打印出来。
  • 测试代码的主函数main,它定义了一个待排序的序列,并调用了heapSort函数对其进行排序,并打印了排序前后的结果。

运行结果


总结

减治法是一种算法设计策略,它的基本思想是将一个规模为n的问题转化为一个规模为n-1的子问题,然后利用子问题的解来求解原问题。减治法可以分为三种类型,分别是减去一个常量、减去一个常数因子和减去一个可变因子。在排序问题中,减治法有很多应用,例如插入排序、堆排序等。

插入排序是一种基于减一法的排序算法,它的过程类似于扑克牌抓牌时的排序。每次从未排序的序列中取出一个元素,将其插入到已排序的序列中合适的位置,使得已排序的序列仍然有序。插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。插入排序是一种稳定的排序算法,也就是说,相同元素的相对顺序不会改变。

堆排序是一种基于减去常数因子的排序算法,它的过程利用了堆这种数据结构。堆是一种特殊的完全二叉树,它满足堆序性质,即每个节点的值都不小于(或不大于)其子节点的值。堆可以分为最大堆和最小堆,分别用于降序和升序排列。堆排序的过程分为两个步骤:建堆和调整堆。建堆是将一个无序的数组构造成一个堆,调整堆是每次将堆顶元素与最后一个元素交换,并将剩余的元素重新调整成一个堆,直到只剩下一个元素。堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。堆排序是一种不稳定的排序算法,也就是说,相同元素的相对顺序可能会改变。
 

相关文章:

分治与减治算法实验: 排序中减治法的程序设计

目录 前言 实验内容 实验目的 实验分析 实验过程 流程演示 写出伪代码 实验代码 代码详解 运行结果 总结 前言 本文介绍了算法实验排序中减治法的程序设计。减治法是一种常用的算法设计技术&#xff0c;它通过减少问题的规模来求解问题。减治法可以应用于排序问题&…...

leetcode两数、三数、四数之和

如有错误&#xff0c;感谢不吝赐教、交流 文章目录 两数之和题目方法一&#xff1a;暴力两重循环&#xff08;不可取&#xff09;方法二&#xff1a;HashMap空间换时间 三数之和题目方法一&#xff1a;当然是暴力破解啦方法二&#xff1a;同两数之和的原理&#xff0c;借助Has…...

使用Docker部署wikitten个人知识库

使用Docker部署wikitten个人知识库 一、wikitten介绍1.wikitten简介2.wikitten特点 二、本地实践环境介绍三、本地环境检查1.检查Docker服务状态2.检查Docker版本 四、部署wikitten个人知识库1.创建数据目录2.下载wikitten镜像3.创建wikitten容器4.查看wikitten容器状态5.检查w…...

【MYSQL】Java的JDBC编程(idea连接数据库)

1. 配置 &#xff08;1&#xff09;新建一个项目 &#xff08;2&#xff09;Build System 那里选择Maven,下一步Create &#xff08;3&#xff09;配置pom.xml文件 首先查看自己的MYSQL版本&#xff1a;进入MySQL命令窗口 我的MYSQL版本是8.0版本的. 下一步&#xff0c;…...

机器学习——主成分分析法(PCA)概念公式及应用python实现

机器学习——主成分分析法&#xff08;PCA&#xff09; 文章目录 机器学习——主成分分析法&#xff08;PCA&#xff09;一、主成分分析的概念二、主成分分析的步骤三、主成分分析PCA的简单实现四、手写体识别数字降维 一、主成分分析的概念 主成分分析&#xff08;PCA&#x…...

手写axios源码系列二:创建axios函数对象

文章目录 一、模块化目录介绍二、创建 axios 函数对象1、创建 axios.js 文件2、创建 defaults.js 文件3、创建 _Axios.js 文件4、总结 当前篇章正式进入手写 axios 源码系列&#xff0c;我们要真枪实弹的开始写代码了。 因为 axios 源码的代码量比较庞大&#xff0c;所以我们这…...

HTB-Time

HTB-Time 信息收集80端口 立足pericles -> root 信息收集 80端口 有两个功能&#xff0c;一个是美化JSON数据。 一个是验证JSON&#xff0c;并且输入{“abc”:“abc”}之类的会出现报错。 Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonPa…...

零基础C/C++开发到底要学什么?

作者&#xff1a;黑马程序员 链接&#xff1a;https://www.zhihu.com/question/597037176/answer/2999707086 先和我一起看看&#xff0c;C/C学完了可以做什么&#xff1a; 软件工程师&#xff1a;负责设计、开发、测试和维护各类型的软件应用程序&#xff1b;游戏开发&#x…...

OpenStack中的CPU与内存超分详解

目录 什么是超分 CPU超分 查看虚拟机虚拟CPU运行在哪些物理CPU上 内存超分 内存预留 内存共享 如何设置内存预留和内存共享 全局设置 临时设置 什么是超分 超分通常指的是CPU或者GPU的分区或者分割&#xff0c;以在一个物理CPU或GPU内模拟多个逻辑CPU或GPU的功能。这…...

main.m文件解析--@autoreleasepool和UIApplicationMain

iOS 程序入口UIApplicationMain详解&#xff0c;相信大家新建一个工程的时候都会看到一个main.m文件&#xff0c;只不过我们很少了解它&#xff0c;现在我们分析一下它的作用是什么&#xff1f; 一、main.m文件 int main(int argc, char * argv[]) {autoreleasepool {return …...

C语言复习之顺序表(十五)

&#x1f4d6;作者介绍&#xff1a;22级树莓人&#xff08;计算机专业&#xff09;&#xff0c;热爱编程&#xff1c;目前在c阶段>——目标C、Windows&#xff0c;MySQL&#xff0c;Qt&#xff0c;数据结构与算法&#xff0c;Linux&#xff0c;多线程&#xff0c;会持续分享…...

学系统集成项目管理工程师(中项)系列10_立项管理

1. 系统集成项目管理至关重要的一个环节 2. 重点在于是否要启动一个项目&#xff0c;并为其提供相应的预算支持 3. 项目建议 3.1. Request for Proposal, RFP 3.2. 立项申请 3.3. 项目建设单位向上级主管部门提交的项目申请文件&#xff0c;是对拟建项目提出的总体设想 3…...

电视盒子哪个好?数码小编盘点2023电视盒子排行榜

随着网络剧的热播&#xff0c;电视机又再度受宠&#xff0c;电视盒子也成为不可缺少的小家电。但面对复杂的参数和品牌型号&#xff0c;挑选时不知道电视盒子哪款最好&#xff0c;小编根据销量和用户评价整理半个月后盘点了电视盒子排行榜前五&#xff0c;对电视盒子哪个好感兴…...

flink动态表的概念详解

目录 前言&#x1f6a9; 动态表和持续不断查询 stream转化成表 连续查询 查询限制 表转化为流 前言&#x1f6a9; 传统的数据库SQL和实时SQL处理的差别还是很大的&#xff0c;这里简单列出一些区别&#xff1a; 尽管存在这些差异&#xff0c;但使用关系查询和SQL处理流并…...

ArcGIS Pro用户界面

目录 1 功能区 1.1 快速访问工具栏 1.2 自定义快速访问工具栏 1.3 自定义功能区选项 1.3.1 添加组和命令 1.3.2 添加新选项卡 2 视图 3 用户界面排列 ​编辑 4 窗格 4.1 内容窗格 4.2 目录窗格 4.3 目录视图&#xff08;类似ArcCatalog&#xff09; 4.4 浏览对话框…...

HDCTF 2023 Pwn WriteUp

Index 前言Pwnner分析EXP: KEEP_ON分析EXP: Minions分析EXP: 后记&#xff1a; 前言 本人是菜狗&#xff0c;比赛的时候只做出来1题&#xff0c;2题有思路但是不会&#xff0c;还是太菜了。 栈迁移还是不会&#xff0c;但又都是栈迁移的题&#xff0c;真头大。得找时间好好学学…...

【 Spring 事务 】

文章目录 一、为什么需要事务(简单回顾)二、MySQL 中的事务使⽤三、Spring 中事务的实现3.1 Spring 编程式事务(手动事务)3.2 Spring 声明式事务(自动事务)3.2.1 Transactional 作⽤范围3.2.2 Transactional 参数说明3.2.3 Transactional 不进行事务回滚的情况3.2.4 Transactio…...

【刷题之路】LeetCode 203. 移除链表元素

【刷题之路】LeetCode 203. 移除链表元素 一、题目描述二、解题1、方法1——在原链表上动刀子1.1、思路分析1.2、代码实现 2、方法2——使用额外的链表2.1、思路分析2.2、代码实现 一、题目描述 原题连接&#xff1a; 203. 移除链表元素 题目描述&#xff1a; 给你一个链表的…...

关于Open Shift(OKD) 中 用户认证、权限管理、SCC 管理的一些笔记

写在前面 因为参加考试&#xff0c;会陆续分享一些 OpenShift 的笔记博文内容为 openshift 用户认证和权限管理以及 scc 管理相关笔记学习环境为 openshift v3 的版本&#xff0c;有些旧这里如果专门学习 openshift &#xff0c;建议学习 v4 版本理解不足小伙伴帮忙指正 对每个…...

活动文章测试(勿删)

大家好&#xff01; 我是CSDN官方博客&#xff01; 恭喜你正式加入CSDN博客&#xff0c;迈上技术成神之路~~ 路漫漫其修远兮——身为技术人&#xff0c;求索之路道阻且艰&#xff0c;但一万次的翘首却比不过一次的前行。 现在&#xff0c;就来开启你的个人博客&#xff0c;发布…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...