浙大数据结构:09-排序3 Insertion or Heap Sort

server/2024/10/21 19:34:32/

这个题跟上个题差不多,只不过是换成了堆排序而已
机翻
在这里插入图片描述

1、条件准备

跟之前一样,oldnum数组存旧数组,newnum数组存新数组

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'int n;
vector<int> oldnum;
vector<int> newnum;

2、主函数

先判断是否为插入排序,否则就进入堆排序,并迭代输出

int main()
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;for(int i=0;i<n;i++){int a;cin>>a;oldnum.push_back(a);}for(int i=0;i<n;i++){int a;cin>>a;newnum.push_back(a);}if(!judgeinsert())heap_sort();return 0;
}

3、judgeinsert函数

递增数组找到尽头再看看后面元素是否匹配。不匹配则为堆排序,再插入一次输出

bool judgeinsert()
{int tag=0;for(int i=0;i<n-1;i++)if(newnum[tag]<=newnum[tag+1])tag++;tag++;for(int i=tag;i<n;i++)if(oldnum[i]!=newnum[i])return 0;cout<<"Insertion Sort\n";int tmp=newnum[tag]; int i;for( i=tag-1;i>=0&&newnum[i]>tmp;i--)newnum[i+1]=newnum[i];newnum[i+1]=tmp;for(int i=0;i<n-1;i++)cout<<newnum[i]<<' ';cout<<newnum[n-1];return 1;
}

4、sift_down函数

建立大根堆所要调用的函数

void sift_down(vector<int>&arr, int start, int end) {// 计算父结点和子结点的下标int parent = start;int child = parent * 2 + 1;while (child <= end) {  // 子结点下标在范围内才做比较// 先比较两个子结点大小,选择最大的if (child + 1 <= end && arr[child] < arr[child + 1]) child++;// 如果父结点比子结点大,代表调整完毕,直接跳出函数if (arr[parent] >= arr[child])return;else {  // 否则交换父子内容,子结点再和孙结点比较swap(arr[parent], arr[child]);parent = child;child = parent * 2 + 1;}}
}

5、堆排序

先建立堆,然后每次把最大的根放在最后,判断完成当前操作是否与newnum数组一样,一样则跳出,再进行一次迭代即可输出

void heap_sort() {cout<<"Heap Sort"<<endl;// 从最后一个节点的父节点开始 sift down 以完成堆化 vector<int> arr=oldnum;for (int i = (n - 1 - 1) / 2; i >= 0; i--) sift_down(arr, i, n - 1);// 先将第一个元素和已经排好的元素前一位做交换,再重新调整(刚调整的元素之前的元素),直到排序完毕int i; int f=1;for ( i = n - 1; i > 0; i--) {f=1;swap(arr[0], arr[i]);sift_down(arr, 0, i - 1);for(int j=0;j<n;j++)if(newnum[j]!=arr[j]){f=0;break;}if(f)break;}i--;swap(arr[0], arr[i]);sift_down(arr, 0, i - 1);for(int i=0;i<n-1;i++)cout<<arr[i]<<' ';cout<<arr[n-1];
}

6、总结

这道题在上一题的基础上完成,难度适中
完整代码如下

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'int n;
vector<int> oldnum;
vector<int> newnum;bool judgeinsert()
{int tag=0;for(int i=0;i<n-1;i++)if(newnum[tag]<=newnum[tag+1])tag++;tag++;for(int i=tag;i<n;i++)if(oldnum[i]!=newnum[i])return 0;cout<<"Insertion Sort\n";int tmp=newnum[tag]; int i;for( i=tag-1;i>=0&&newnum[i]>tmp;i--)newnum[i+1]=newnum[i];newnum[i+1]=tmp;for(int i=0;i<n-1;i++)cout<<newnum[i]<<' ';cout<<newnum[n-1];return 1;
}void sift_down(vector<int>&arr, int start, int end) {// 计算父结点和子结点的下标int parent = start;int child = parent * 2 + 1;while (child <= end) {  // 子结点下标在范围内才做比较// 先比较两个子结点大小,选择最大的if (child + 1 <= end && arr[child] < arr[child + 1]) child++;// 如果父结点比子结点大,代表调整完毕,直接跳出函数if (arr[parent] >= arr[child])return;else {  // 否则交换父子内容,子结点再和孙结点比较swap(arr[parent], arr[child]);parent = child;child = parent * 2 + 1;}}
}void heap_sort() {cout<<"Heap Sort"<<endl;// 从最后一个节点的父节点开始 sift down 以完成堆化 vector<int> arr=oldnum;for (int i = (n - 1 - 1) / 2; i >= 0; i--) sift_down(arr, i, n - 1);// 先将第一个元素和已经排好的元素前一位做交换,再重新调整(刚调整的元素之前的元素),直到排序完毕int i; int f=1;for ( i = n - 1; i > 0; i--) {f=1;swap(arr[0], arr[i]);sift_down(arr, 0, i - 1);for(int j=0;j<n;j++)if(newnum[j]!=arr[j]){f=0;break;}if(f)break;}i--;swap(arr[0], arr[i]);sift_down(arr, 0, i - 1);for(int i=0;i<n-1;i++)cout<<arr[i]<<' ';cout<<arr[n-1];
}
int main()
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;for(int i=0;i<n;i++){int a;cin>>a;oldnum.push_back(a);}for(int i=0;i<n;i++){int a;cin>>a;newnum.push_back(a);}if(!judgeinsert())heap_sort();return 0;
}

http://www.ppmy.cn/server/133702.html

相关文章

Qt 窗口的模态类型

setWindowModality函数 void setWindowModality(Qt::WindowModality windowModality); setWindowModality 是QWidget类的一个成员函数&#xff0c;它允许你设置窗口的模态类型。模态性定义了窗口如何与其他窗口交互&#xff0c;以及用户在与模态窗口交互之前是否必须先与之交互…

Vue Data UI——Vue 3 数据可视化组件库

文章目录 1、Vue Data UI2、核心特点2.1.Vue 3 的深度集成2.2 丰富的可视化组件2.3 灵活的定制性2.4 易于集成2.5 文件导出功能2.6 多主题支持3、如何在项目中使用 Vue Data UI?3.1 安装 Vue Data UI3.2 全局注册组件3.3 局部引入组件3.4 使用通用组件3.5 TypeScript 集成4、总…

FFmpeg 4.3 音视频-多路H265监控录放C++开发二 : 18.04ubuntu安装,linux 下build ffmpeg 4.3 源码 并测试

测试环境 ubuntu 18.04 64 位&#xff0c;安装vmware and ubuntu 安装后调整 分辨率&#xff1a; 让windows 可以和 linux 互相复制黏贴 sudo apt-get autoremove open-vm-tools sudo apt-get update sudo apt-get install open-vm-tools-desktop 一直Y reboot 依赖安装 sud…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-14

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-14 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-14目录1. Are Large Language Models State-of-the-art Quality Estimators for Machine Translation of User-generated Conten…

形式架构定义语言(ADL)

简介 形式规范 多年来&#xff0c;学术界一直在试图通过使用与测试截然不同且更加主动的方法来确保程序语义的正确执行&#xff1a;形式化方法。研究者们认为这种方法通过更加精确、无二义性的描述来达到让程序绝对地按照设计者的思想执行的目的。这种思想早期体现在Floyd在1…

京东云主机和云服务器有啥区别?轻量云主机就是轻量应用服务器吗?

京东云主机和云服务器有啥区别&#xff1f;轻量云主机就是轻量应用服务器吗&#xff1f;云主机就是云服务器的意思&#xff0c;是京东云给自家云服务器取的名字&#xff0c;阿里云叫云服务器ECS&#xff0c;腾讯云叫云服务器CVM&#xff0c;京东云服务器叫云主机&#xff0c;京…

Lua脚本的原子性

Lua脚本之所以被认为是原子性的,主要源于Redis的内部实现机制和Lua脚本的执行方式。以下是对Lua脚本原子性的详细解释: 一、Redis的单线程模型 Redis是一个基于内存、可基于Key-Value等多种数据结构的存储系统,它使用单线程模型来处理客户端的请求。这意味着在任何给定的时…

代码随想录day6| 242.有效的字母异位词 、349. 两个数组的交集、 202. 快乐数 、 1. 两数之和

代码随想录day6| 242.有效的字母异位词 、349. 两个数组的交集、 202. 快乐数 、 1. 两数之和 242.有效的字母异位词思路步骤 349. 两个数组的交集思路步骤 202. 快乐数思路步骤 1. 两数之和思路步骤 242.有效的字母异位词 思路 使用暴力解法时间复杂度为O(n^2)这道题需要判断…