堆排序快速排序插入排序

news2024/11/15 21:33:14

堆排序

数据结构使用的是1 dimension的数组来作为二叉树的堆结构,所以并没有使用结构体,而是直接使用了数组

而且堆是完全二叉树,也就是除了最后一层以外,其他层都是满二叉树,最后一层可能不满,所以1dimension数组产生二叉树就很方便,第一个数字就是根节点,然后是左右子节点,层序遍历即可

性质:完全二叉树的孩子节点是父节点的2xn或者2x n+1

第一步:产生堆,要满足性质,每个父节点的值比孩子节点都要大(小),递推的话根节点就是最大(小)值

这里要注意,孩子节点是父节点的2xn或者2x n+1,所以从len/2-1的位置开始调整即可也即是最后一个父节点

    for(int i = len/2 - 1; i >= 0; i--)   //create heap struct
        max_heapify(i, len - 1);

第二步:分区,两个区,堆区和已经排好序的区,堆区是无序的,每次将堆的根节点也就是最大值移到末尾,然后再次产生堆,由于堆已经是大小一致,只要将根节点移到合适的位置即可

输入:8 9 10 1 3 6 5 4 2 7 0

图来自 https://www.runoob.com/w3cnote/heap-sort.html

1.7 堆排序 | 菜鸟教程 (runoob.com)​www.runoob.com/w3cnote/heap-sort.html

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
vector<int> s6;

void printvec(vector<int> a){
    for(int i=0; i<a.size();i++){
        cout<<a[i];
        if(i!=(a.size()-1))
            cout<<" ";
    }
    cout<<endl;
}

void max_heapify(int start, int end) {
    int dad = start;
    int son = dad * 2 + 1;
    while(son <= end) {
        if(son + 1 < end && s6[son] < s6[son + 1])
            son++;
        if(s6[dad] > s6[son]) {
            return;
        }
        else {
            swap(s6[son], s6[dad]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
    return;
}

int main(void){
    int n, num;
    cin>>n;
    for(int i=0; i<n; i++){
        cin>>num;
        s6.push_back(num);
    }
    int len = s6.size();
    for(int i = len/2 - 1; i >= 0; i--)   //create heap struct
        max_heapify(i, len - 1);
    for(int i = len - 1; i > 0; i--) { //move the largest to end and recreate heap struct
        swap(s6[0], s6[i]);
        max_heapify(0, i - 1);
    }
    printvec(s6);
    return 0;
}

1.7 堆排序 | 菜鸟教程 (runoob.com) 

#include<iostream>
using namespace std;
int arr[] = {2, 9, 6, 1, 5, 8, 7, 11, 100, 30, 31, 38, 60, 50, 30};
void printvec(int len) {
    printf("%d", arr[0]);
    for(int i = 1; i < len; i++) printf(" %d", arr[i]);
}
void maxheapify(int start, int end) {
    int dad = start;
    int son = dad * 2 + 1;
    while(son < end) {           //是while不是if
        if(son+1 < end && arr[son+1] > arr[son]) //子节点的最大值
            son++;
        if(arr[dad] > arr[son]) return;   //父节点是最大值返回
        if(arr[dad] < arr[son]) {
            swap(arr[dad], arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}
void heapsort(int len) {
    for(int i = len/2 - 1; i >= 0; i--) //len/2-1拿到最后一个父节点的序号,从0开始
        maxheapify(i, len);   //从下到上, generate heap
    for(int i = len - 1; i > 0; i--) {   
        swap(arr[0], arr[i]);
        maxheapify(0, i-1); //从上到下
    }
}
int main(int argc, char **argv) {
    int len = sizeof(arr)/sizeof(*arr);
    if(len==1) {
        printvec(len);
        return EXIT_SUCCESS;
    }
    heapsort(len);
    printvec(len);
    return EXIT_SUCCESS;
}

 

快速排序

选定(枢轴)支点pivot,然后配置左右的定位符i,j

支点可以任意选取,支点所在值记为A,左右定位符一般是0, len - 1

  1. 从右向左扫描,若是值小于A,则将该值放到支点,然后此处产生空洞L
  2. 从左向右扫描,若是值大于A,则将该值放到空洞L所在位置,此处产生空洞,用A来填补即可
  3. 分片,以支点所在位置分片,左右分别进行1、2,不断递归直到只剩一个值
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
vector<int> v6;

void printvec(vector<int> a){
    for(int i=0; i<a.size();i++){
        cout<<a[i];
        if(i!=(a.size()-1))
            cout<<" ";
    }
    cout<<endl;
}

void quick_sort(int start, int end) {
    int i = start;
    int A = v6[start];
    int j = end;
    if(i < j) {
        while(i < j) {
            while(i < j && v6[j] >= A)
                j--;
            if(i < j) {
                v6[start] = v6[j];
                i++;
            }
            while(i < j && v6[i] < A)
                i++;
            if(i < j) {
                v6[j] = v6[i];
                v6[i] = A;
                j--;
            }
        }
        v6[i] = A;//填补最后的空洞
        quick_sort(start, i - 1);
        quick_sort(i + 1, end);
    }
    return;
}

int main(void){
    int n, num;
    cin>>n;
    for(int i=0; i<n; i++){
        cin>>num;
        v6.push_back(num);
    }
    int len = v6.size();
    quick_sort(0, len - 1);
    printvec(v6);
    return 0;
}

 快速排序 | 菜鸟教程 (runoob.com)

#include<iostream>
using namespace std;
int arr[] = {2, 9, 6, 1, 5, 8, 7, 11, 100, 30, 31, 38, 60, 50, 30};
void printvec(int len) {
    printf("%d", arr[0]);
    for(int i = 1; i < len; i++) 
        printf(" %d", arr[i]);
}
void quicksort(int l, int r) {
    if(l>=r) return;
    int h = arr[l];
    int start = l;
    int end = r;
    while(l < r) {
        while(l < r && arr[r] >= h)
            r--;
        if(l<r) arr[l++]= arr[r];
        while(l < r && arr[l] < h)
            l++;
        if(l<r) arr[r--] = arr[l];
    }
    arr[l] = h; //l==r
    quicksort(start, l-1);
    quicksort(l+1, end);
}
int main(int argc, char **argv) {
    int len = sizeof(arr)/sizeof(*arr);
    if(len==1) {
        printvec(len);
        return EXIT_SUCCESS;
    }
    quicksort(0, len - 1);
    printvec(len);
    return EXIT_SUCCESS;
}

 

插入排序

1 2 3 9 6 8 7

1 2 3 9是已经排好序的序列, 然后后一个是6,将6插入到已经排好序的1 2 3 9, 应该要放到3和9之间, 所以插入到3和9之间,也就是1 2 3 6 9,所以叫做插入排序的呢

得到1 2 3 6 9 8 7

接着就是要就是要处理其他的剩下的

C++

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

void printvec(vector<int> a){
    for(int i=0; i<a.size();i++){
        cout<<a[i];
        if(i!=(a.size()-1))
            cout<<" ";
    }
    cout<<endl;
}

int main(void){
    vector<int> s0;
    int n, num;
    cin>>n;
    for(int i=0; i<n; i++){
        cin>>num;
        s0.push_back(num);
    }
    for(int i=0; i<n-1; i++){
        if(s0[i+1]<s0[i]){
            for(int j=0; j<=i; j++){
                if(s0[j]>=s0[i+1]){
                    s0.insert(s0.begin()+j, s0[i+1]);
                    s0.erase(s0.begin()+i+2);
                }
            }
        }
    }
    printvec(s0);
    return 0;
}

 

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

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

相关文章

基于jeecgboot的flowable流程支持服务任务的功能

1、描述 Java服务任务用于调用外部Java类。 2、图形表示法 服务任务可视化为圆角矩形&#xff0c;左上角有一个小齿轮图标&#xff0c;如下图&#xff1a; 3、XML表示 有三种方法声明如何调用Java逻辑&#xff0c;下面分别介绍&#xff1a; 调用固定的类 使用flowable:cla…

Flask打开调试模式

调试模式 Flask支持本地开发&#xff0c;但是每次修改代码后需要手动重新启动程序&#xff0c;这不是很友好&#xff0c;事实上Flask支持调试模式来做到更好&#xff0c;Flask服务会在代码更改时自动重新加载&#xff0c;如果出现问题&#xff0c;还能提供调试器以供调试 如何…

docker登陆MySQL提示密码错误,Navicat也连接不上

问题原因 今天在操作自己云服务器MySQL数据库的时候发现使用root进行远程登录的时候被拒绝了&#xff0c;一直提示Access denied for user ‘root‘‘localhost‘ (using password: YES)。 可以确认自己账号密码是没有错的。后来以为是远程访问出问题了&#xff0c;进入到容器…

JavaSE基础篇:泛型说明

本文整理自B站&#xff1a;JavaSE强化教程泛型&#xff0c;由点到面的讲解了整个泛型体系第一章&#xff1a;泛型概述一&#xff1a;泛型概念二&#xff1a;泛型类1&#xff1a;泛型类使用2&#xff1a;泛型类派生子类1)&#xff1a;子类也是泛型类2)&#xff1a;子类不是泛型类…

SQL进阶笔记

SQL进阶笔记 CASE表达式 简单case表达式 case sexwhen 1 then 男when 2 then 女else 其他 end搜索case表达式 case when sex 1 then 男when sex 2 then 女else 其他 end编写SQL语句的时候需要注意&#xff0c;在发现为真的WHEN子句时&#xff0c;CASE表达式的真假值判断就会中…

Java并发编程(一)—— FutureTask超详细教程

一、前言 创建线程有几种方式?这个问题的答案应该是可以脱口而出的吧: 继承 Thread 类实现 Runnable 接口但这两种方式创建的线程是属于三无产品: 没有参数没有返回值没办法抛出异常用着三无产品总是有一些弊端,其中没办法拿到返回值是最让人不能忍的,于是 Callable 就诞…

TeamsApp LukcyDraw升级之路 之 DB Infra 篇

今天继续 LuckyDraw 的升级之路&#xff0c;之前在1500以上用户同时使用的时候&#xff0c;特别是在短时间内大家一起点击参与抽奖参的时候&#xff0c;服务会出现大量的错误&#xff0c;分析后发现&#xff0c;出现错误的原因基本都是 Azure Storage Table 返回的。当时使用 A…

【GRU回归预测】基于matlab卷积神经网络结合门控循环单元CNN-GRU数据预测(多输入单输出)【含Matlab期源码 2274期】

⛄一、CNN-GRU数据预测 1 理论基础 1.1 CNN算法 负荷序列数据为一维数据&#xff0c;用一维卷积核对数据进行卷积处理&#xff0c;以获取数据的特征。 现设定卷积核的维度为3&#xff0c;移动步长为1&#xff0c;对输入数据进行卷积&#xff0c;以获得特征图图谱&#xff0c;即…

记录那不用百度的美好代码

努力工作&#xff0c;日益消瘦&#xff0c;总有些代码不想记住。我称之为&#xff1a;拿来即用系列 一&#xff1a;格式化时间 1.去除时间的T // 去除日期中T function timeFormatSeconds(time) {if(!time) return time;var date time.substr(0, 10); //年月日var hours ti…

jsp+ssm计算机毕业设计宠物商城【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

基于SPRINGBOOT的健康饮食管理系统

11-8开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 基于springboot框架&#xff0c;通过对事物健康程度的总结与归纳&#xff0c;进行软件设计&#xff0c;并通过优秀的…

go 语言Http服务器远程执行shell命令

背景 想要在服务器上起一个http服务器&#xff0c;用来远程执行shell命令并且返回。 基础版 package mainimport ("io""log""net/http" )func main() {// Hello world, the web serverhelloHandler : func(w http.ResponseWriter, req *http.R…

性能脚本:用案例和图示帮你理解HTTP协议

当前使用得最为广泛的应用层协议就是 HTTP 了。我想了好久,还是觉得应该把 HTTP 协议写一下。 因为做性能测试分析的人来说,HTTP 协议可能是绕不过去的一个槛。在讲 HTTP 之前,我们得先知道一些基本的信息。 HTTP(HyperText Transfer Protocol,超文本传输协议),显然是…

linux shell编程

linux shell编程1.shell脚本概述2.脚本的调用形式3.shell脚本语法3.1 脚本开头标识3.2 脚本注释3.3 给脚本加上可执行权限3.4 shell脚本的运行方式3.5 检测脚本是否正确3.6 重定向的使用3.7 获取上一条命令的执行结果4.变量4.1 变量的定义和使用4.2 从键盘上读取变量&#xff1…

(十七)Vue之自定义指令

文章目录自定义指令局部指令回调函数形式配置对象形式全局配置回调函数形式配置对象形式Vue学习目录 上一篇&#xff1a;&#xff08;十六&#xff09;Vue之内置指令 先看两个需求&#xff1a; 需求1&#xff1a;定义一个v-big指令&#xff0c;和v-text功能类似&#xff0c;…

陈表达学VBA-msgbox辨别用户选择和代码调用

今天有个老客户提出需求&#xff1a; 模块&#xff1a;sub 过程A( ) ①如果是单独使用时则显示msgbox选择消息框 ②如果A过程调用B过程&#xff0c;则不显示消息框&#xff0c;默认选择是 msgbox没有设置默认值这个功能&#xff0c;msgbox也没有参数可以失败是用户点击还是代…

pytorch基础操作(六)利用L2范数(权重衰减)解决线性模型过拟合问题

一、一些概念 训练误差&#xff08;training error&#xff09; 是指&#xff0c;模型在训练数据集上计算得到的误差。 泛化误差&#xff08;generalization error&#xff09; 是指&#xff0c;模型应⽤在同样从原始样本的分布中抽取的⽆限多数据样本时&#xff0c;模型误差的…

【Linux】Linux基本指令

Linux基本指令1.ls指令2.pwd指令3.cd指令3.touch 指令4.mkdir指令5. rmdir指令 && rm 指令5.1 rmdir5.2 rm6.tree 指令7.man指令8.cp指令9.mv指令10. cat指令11.echo指令12.more指令13.less指令14.wc指令15.head指令16.tail指令17. | &#xff08;管道指令&#xff09;…

每天五分钟机器学习:PCA算法如何确定数据压缩降维的最佳维度?

本文重点 上节课程中我们已经学习了pca算法,已经知道了如何将n维特征变量降到k维,k是PCA算法的一个参数,也被称为主成分的数量。那么现在就产生了一个问题,这个问题就是如何选择K,因为PCA要做的就是要尽量减少投射的平均均方误差,所以K的选择很关键。 平均均方误差 其中…

22.MongoDB删除操作效率及相关问题验证

最近遇到一个了一个MongoDB数据删除的问题&#xff0c;需要一次性删除上线即1.5年前~1年前的数据且之后每天清空一年过期的数据。在数据量比较大的情况下何种方式的删除效率最高是一个值得研究的问题&#xff0c;本文通过实际测试找出其中规律。 本文采用腾讯云mongodb集群进行…