目录

1.直接选择排序

1.1 思想

1.2 代码

2.堆排序

2.1 向下调整算法

2.1.1 代码

2.2 建堆

2.2.1 代码

  2.3 正式排序

2.3.1 代码

3. 冒泡排序

3.1 思路

3.1.1 单趟排序

3.1.2 多趟排序

3.1.3优化

3.2 代码


1.直接选择排序

1.1 思想

        每次从未排序区中选择一个最小\最大的数字插入到排序区的最后一个位置。具体如下图所示:

优化:每一次遍历只选择一个最小的数,有些浪费,如果此时选择一个最小的数的同时也选一个最大的数,此时就能节省一半的时间。那么此时的思路如下:每次选择最小和最大的数放在最左边和最右边,每一次缩小左边界和右边界。

总体思路如下

①维护两个下标begin和end作为边界。

②遍历[begin,end],设置mini即最小元素的下标、maxi即最大元素的下标为begin,若当前元素比mini所指的元素要小,那么就更新mini,同理更新maxi。

③循环之后将最大的元素与end元素进行交换,将最小的元素和begin进行交换。

④设置最新的begin和end,即更新为begin+1,end-1;

1.2 代码

错误代码演示

void Swap(int* a,int* b)
{int tmp = *a;*a = *b;*b = tmp;
}// 直接选择排序
void selectSort(int* arr, int size)
{// 维护两个边界int begin = 0, end = size - 1;while (begin < end)// 等于的时候已经排序完毕{// 定义两个下标为最小元素和最大元素的下标int mini = begin;int maxi = begin;// 遍历闭区间内的所有数字,更新mini和maxifor (int i = begin + 1; i <= end; i++){if (arr[i] < arr[mini]){mini = i;// 此时更新mini}if (arr[i] > arr[maxi]){maxi = i;// 此时更新maxi}}// 循环结束之后,maxi是当前最大元素的下标,mini是当前最小元素的下标// 交换maxi元素和end元素。交换mini元素和begin元素Swap(&arr[mini],&arr[begin]);Swap(&arr[maxi],&arr[end]);// 更新左右边界--end;++begin;}
}

错误的原因:如果遇到这种特殊情况,begin和min交换,max和end交换,此时相当于没有做出任何改变!第一步交换begin和min的时候是没有问题的,但是此时的maxi指向的并不是正确的位置,因为20已经被交换到最后一个位置了,此时需要重新计算maxi的位置。

        由于begin和mini交换,此时的最大值已经在mini处了,所以此时更新maxi为mini。

正确代码如下

void Swap(int* a,int* b)
{int tmp = *a;*a = *b;*b = tmp;
}// 直接选择排序
void selectSort(int* arr, int size)
{// 维护两个边界int begin = 0, end = size - 1;while (begin < end)// 等于的时候已经排序完毕{// 定义两个下标为最小元素和最大元素的下标int mini = begin;int maxi = begin;// 遍历闭区间内的所有数字,更新mini和maxifor (int i = begin + 1; i <= end; i++){if (arr[i] < arr[mini]){mini = i;// 此时更新mini}if (arr[i] > arr[maxi]){maxi = i;// 此时更新maxi}}// 循环结束之后,maxi是当前最大元素的下标,mini是当前最小元素的下标// 交换maxi元素和end元素。交换mini元素和begin元素Swap(&arr[mini],&arr[begin]);// 如果此时maxi和begin是重合的,那么需要重新找到maxiif (maxi == begin){maxi = mini; //此时mini和begin交换,max被换到了mini的位置上}Swap(&arr[maxi],&arr[end]);// 更新左右边界--end;++begin;}
}

2.堆排序

        堆排序的内容在之前堆的学习中已经学过了,这里简单再过一遍,如果还是有读者不懂,可以参照堆排序这篇文章。

2.1 向下调整算法

        向下调整算法的前提是左右子树都是大堆或小堆;此时如果排的是升序,那么此时需要的是大堆,每次选择堆顶的数和最后一个数进行交换,再向下调整选择次大的数和倒数第二个数交换即可~

        向下调整算法的逻辑:

①首先选择左孩子作为孩子中最大的节点,如果右孩子比左孩子大,那么就更新右孩子为最大的节点。

②如果当前节点的孩子节点没有越界,那么进入循环。首先判断右孩子是否越界并且右孩子如果比左孩子大,那么更新child节点为右孩子。

③在判断孩子节点和父亲节点哪一个大,如果孩子节点大那么就进行交换,如果父亲节点比孩子节点要大,说明本身就是大堆,那么就不需要进行调整了,此时直接退出循环即可。

2.1.1 代码

void adjustDown(int* arr, int n, int root)
{int parent = root;int child = 2 * parent + 1;// 默认左节点最大while (child < n)// 只要孩子节点不越界,那就继续循环{if (child + 1 < n && arr[child + 1] > arr[child]){// 说明右孩子更大,更新右孩子++child;}// 此时父亲节点和最大的孩子的节点进行判断if (arr[parent] < arr[child]){Swap(&arr[parent], &arr[child]);// 更新父亲节点,向下调整parent = child;child = child * 2 + 1;}else{// 此时满足大堆的条件,直接返回即可break;}}}

2.2 建堆

        每次从最后一个非叶子节点进行向下调整。

2.2.1 代码

// 堆排序 :数组、数组长度
void heapSort(int* arr,int n) 
{// 建堆// 从最后一个非叶子结点开始向下调整for (int i = (n-1-1)/2; i >= 0; --i){adjustDown(arr,n,i);}
}

  2.3 正式排序

        将堆建好之后,每次取大堆堆顶的数,交换到最后一个位置,再取出次大的数交换倒数第二个位置,以此类推;每次交换的时候需要向下调整,形成堆,才能取出最大的数。

2.3.1 代码

// 堆排序 :数组、数组长度
void heapSort(int* arr, int n)
{// 建堆// 从最后一个非叶子结点开始向下调整for (int i = (n - 1 - 1) / 2; i >= 0; --i){adjustDown(arr, n, i);}// 排序int end = n - 1;while (end > 0) // 1个数就不需要排序了 {Swap(arr[end], arr[0]); // 堆顶和最后一个元素交换// 继续调整成堆adjustDown(arr,end,0); // 将前n-1个数进行向下调整--end;}
}

建堆的时间复杂度是O(n),堆排序的时间复杂度是n*Logn

3. 冒泡排序

3.1 思路

3.1.1 单趟排序

        从第二个元素比较前一个元素,如果第二个元素小于第一个元素,就交换,循环一直到最后一个元素为止;

        也就是说,每一次排序只会将最大的数字放到最后面,那么需要多少次排序呢?

3.1.2 多趟排序

        我们只需要控制右边界就可以了,将右边界每次减少1个。

3.1.3优化

        一趟排序结束后,没有交换元素,说明元素已经有序,那么就直接退出循环。

3.2 代码

// 冒泡排序void BubbleSort(int* arr, int size)
{int end = size;// 每一趟确定一个最大数while (end > 0){int flag = 1;// 单趟排序for (int i = 1; i < end; ++i){if (arr[i - 1] > arr[i]){Swap(&arr[i - 1], &arr[i]);flag = 0;}}if (flag == 1){break;// 提前退出循环}--end;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fluent Bit系列:字符集转码测试(下)

#作者&#xff1a;程宏斌 文章目录fluent-bit 1.9.4 转换测试结论接上篇&#xff1a;《Fluent Bit系列&#xff1a;字符集转码测试&#xff08;上&#xff09;》https://blog.csdn.net/qq_40477248/article/details/150776142?spm1001.2014.3001.5501fluent-bit 1.9.4 转换测试…

redis-缓存-持久化

redis-缓存-持久化一、来因宫1、啥叫持久化&#xff1f;为何需要持久化&#xff1f;2、redis持久化方案2.1、RDB - 快照持久化A、定义原理B、快照生成流程&#xff1a;Copy-on-Write&#xff08;写时复制&#xff09;C、dump.rdb文件说明D、RDB 数据恢复流程E、RDB的优缺点2.2、…

C++11(Linux/GCC)字节序工具

#pragma once #include <cstdint> #include <climits> #include <type_traits> // 用于类型检查// 端序宏获取&#xff08;保持原有逻辑&#xff09; #if __has_include(<endian.h>)#include <endian.h> #elif __has_include(<bits/endian.h…

【MTCNN网络结构记忆卡片】--003nets.py

&#x1f9e0; MTCNN网络结构记忆卡片 &#xfffd;&#xfffd; 基础概念速查 &#x1f524; 库引入&#xff1a;import torch 和 import torch.nn as nn import torch # PyTorch深度学习框架 import torch.nn as nn # nn Neural Networks (神经网络)&#x1f3d7;️…

可视化-模块1-HTML-03

1.发现问题<p>大数据可视化技术及应用课程</p> <img src"pic/图片2.png" width"300" height"300"/><p></p><img />HTML 标签按闭合方式只分两类&#xff1a;双标签&#xff08;paired / container&#xff…

前端开发:详细介绍npm、pnpm和cnpm分别是什么,使用方法以及之间有哪些关系

目录 npm、pnpm和cnpm分别是什么 npm pnpm cnpm NPM包管理器 使用npm管理&#xff0c;创建/初始化项目 修改npm镜像&#xff08;npm源设置&#xff09; 基本命令 安装依赖项 下载特定版本的依赖 下载开发依赖 下载全局依赖&#xff08;全局安装&#xff09; 升级依赖项 根据依赖…

我们为你连接网络,安装驱动程序

Windows 11 家庭版/专业版在安装时默认要求联网&#xff0c;其实可以跳过。在这个联网界面按下 Shift F10 打开命令行。输入以下命令并回车&#xff1a;OOBE\BYPASSNRO系统会自动重启&#xff0c;回到联网界面。这时会多出一个 “我没有 Internet” 选项&#xff0c;点它&…

智慧交通夜间逆光误检率↓81.4%!陌讯多模态融合算法在主干道监测的落地优化

一、智慧交通视觉检测的行业痛点智慧交通作为城市基建的核心环节&#xff0c;其视觉检测系统&#xff08;车辆识别、车牌匹配、交通事件预警&#xff09;的可靠性直接影响通行效率与交通安全。但根据《2023 年中国智慧交通发展报告》数据&#xff0c;当前主流方案仍面临三大核心…

Java和数据库的关系

数据库本身是一个独立的、巨大的知识领域&#xff0c;但“数据库的使用、优化和深度理解”绝对是Java后端工程师进阶的核心组成部分。 它们不是分开的&#xff0c;而是紧密耦合、相辅相成的关系。你可以这样理解&#xff1a; 数据库&#xff08;MySQL, Oracle等&#xff09; 就…

Socket some functions

setsockopt 简介setsockopt 是用于设置套接字&#xff08;socket&#xff09;选项的系统调用函数&#xff0c;允许用户对套接字的行为进行精细控制。通过调整选项参数&#xff0c;可以优化网络通信性能、修改超时设置、启用特殊功能等。该函数在 POSIX 系统和 Windows 平台均有…

玩转深度学习数据填补!CNN-GRU组合模型数据填补(四个案例数据)

这两段MATLAB代码&#xff08;BABJ.m 和 CNN_GRUQSTB.m&#xff09;分别完成数据预处理与缺失值标识和基于CNN-GRU混合神经网络的缺失值预测填补任务。以下是详细分析&#xff1a; 一、主要功能 BABJ.m • 功能&#xff1a;从多个Excel文件中读取数据&#xff0c;匹配并合并多个…

基于开源AI智能名片链动2+1模式S2B2C商城小程序的营销创新研究——以“种草”实践践行“以人为本”理念

摘要&#xff1a;本文聚焦于营销本质&#xff0c;强调创造和维护与消费者有价值关系的重要性&#xff0c;指出企业需回归消费者视角提供有价值产品和服务。深入探讨“种草”作为科特勒“以人为本”理念在中国市场的最佳实践&#xff0c;分析其意义与价值。同时&#xff0c;引入…

基于SpringBoot+Vue的智能停车场管理系统 停车管理小程序

&#x1f525;作者&#xff1a;it毕设实战小研&#x1f525; &#x1f496;简介&#xff1a;java、微信小程序、安卓&#xff1b;定制开发&#xff0c;远程调试 代码讲解&#xff0c;文档指导&#xff0c;ppt制作&#x1f496; 精彩专栏推荐订阅&#xff1a;在下方专栏&#x1…

01数据结构-归并排序和计数排序

01数据结构-归并排序和计数排序1.归并排序1.1归并排序概述1.2归并排序的执行流程1.2.1递(分裂)的过程1.2.2归(合并)的过程1.3归并排序的代码实现2.计数排序2.1算法思想2.2计数排序的改进2.2.1优化12.2.2优化21.归并排序 1.1归并排序概述 归并排序&#xff0c;其排序的实现思想…

SQL注入2----(sql注入数据类型分类)

一.前言本章节我们来讲解一下sql注入的分类&#xff0c;主要分为四类&#xff0c;数字型、字符型、搜索型、xx型。二.数字型数字型注入的时候&#xff0c;是不需要考虑单\双引号闭合问题的&#xff0c;因为sql语句中的数字是不需要用引号括起来的&#xff0c;如下mysql> sel…

Elasticsearch Rails 实战全指南(elasticsearch-rails / elasticsearch-model)

一、背景与生态总览 elasticsearch-rails&#xff1a;面向 Rails 的“伴生库”&#xff0c;为 Rails 项目带来 Rake 任务、日志埋点、模板等特性。elasticsearch-model&#xff1a;把 ES 能力“混入”到 Ruby 模型&#xff08;ActiveRecord/Mongoid&#xff09;&#xff0c;提供…

第三阶段数据库-2:数据库中的sql语句

1_数据库操作&#xff08;1&#xff09;注释&#xff1a;-- 单行注释 /**/ 多行注释&#xff08;2&#xff09;创建数据库&#xff1a;create database 数据库名-- create database 数据库名 create database db_first;(3&#xff09;查询数据库&#xff1a;if exsists(select…

python中的filter函数

目录 定义与参数说明 特点 使用场景 常用操作 筛选偶数 去除空字符串 筛选正数 筛选字典 配合集合与元组 注意事项 定义与参数说明 filter函数是Python内置的高阶函数之一&#xff0c;用于筛选可迭代对象中的元素&#xff0c;根据返回值的布尔结果&#xff08;True 或…

BERT(Bidirectional Encoder Representations from Transformers)模型详解

一、BERT 简介BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由 Google 在 2018 年提出的一种预训练语言表示模型。它基于 Transformer 编码器结构&#xff0c;首次提出了 双向上下文建模 的方法&#xff0c;大幅度提升了自然语言处理…

【开题答辩全过程】以 基于Springboot+微信小程序的网上家教预约系统的设计与实现-开题为例,包含答辩的问题和答案

个人简介&#xff1a;一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧…