数据结构与算法之排序算法-选择排序

排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~

那么我将通过几篇文章,将排序算法中各种算法细化的,详尽的为大家呈现出来:

📚 非线性时间比较类

📕 插入类排序:数据结构与算法之排序算法-插入排序-CSDN博客

📖 直接插入排序

📖 希尔排序

📕 交换类排序:数据结构与算法之排序算法-快速排序(分治)-CSDN博客

📖 冒泡排序

📖 冒泡排序-优化

📖 快速排序(Hoare,挖坑法,前后指针法)

📖 快速排序-优化

📕 选择类排序:[本篇]

📖 简单选择排序

📖 堆排序

📕 归并类排序:数据结构与算法之排序算法-归并排序-CSDN博客

📖 归并排序

📚 线性时间非比较

📕 非比较类排序:数据结构与算法之排序算法-(计数,桶,基数排序)-CSDN博客

📖 计数排序

📖 桶排序

📖 基数排序

一、选择排序

稳定性:不稳定

时间复杂度:O(n^2)

额外空间复杂度:O(1)

选择排序是排序算法中最简单直观的排序算法之一,还记得冒泡排序吗?在冒泡排序中,我们是通过多次遍历数组,然后将此次遍历中最大的元素放到遍历范围的最后,选择排序和冒泡排序有一些相似之处:

冒泡排序的核心思想:不断寻找最大的元素并放到最后。
选择排序的核心思想:不断寻找最小的元素并放到最前。

① 选择排序(循环嵌套)

📚 算法思想

选择排序:通过两层循环,外层循环(int i = 0;i < len - 1;i++)代表从 i 开始,进行内层循环(int j = i + 1;j < len;j++)来寻找此次循环中的最小值,并将最小值放在 i 的位置~

图示

📖 代码示例

    public static void selectionSort(int[] arr){
        int len = arr.length;
        for(int i = 0;i < len - 1;i++){
            int minIndex = i;
            for(int j = i + 1;j < len;j++){
                if(arr[j] < arr[minIndex]){
                    minIndex = j;
                }
            }
            swap(arr,i,minIndex);
        }
    }

② 选择排序(双指针)

📚 算法思想

通过每次迭代同时找到当前范围内的最大值和最小值,并且将它们分别放到数组的两端,这样可以减少直接插入排序算法的迭代次数,做到提高效率(但其实没卵用...)

使用两个指针left和right,分别指向数组的起始位置和结束位置
每次迭代中,找到当前范围内[left,right]的最小值和最大值
将最小值放到left位置,将最大值放到right位置
然后缩小范围,left++,right--,直到left和right相遇。

📖 代码示例

    public static void selectSort2(int[] array){
        int left = 0;
        int right = array.length - 1;
        while(left < right){
            int minIndex = left;
            int maxIndex = left;
            System.out.println(Arrays.toString(array));
            for(int i = left + 1;i <= right;i++){
                if(array[minIndex] > array[i]){
                    minIndex = i;
                }
                if(array[maxIndex] < array[i]){
                    maxIndex = i;
                }
            }
            swap(array, left, minIndex);
            if(left == maxIndex){
                maxIndex = minIndex;
            }
            swap(array, right, maxIndex);
            left++;
            right--;
        }
    }

(可以实现一下用来练习自己的代码能力,实际应用的话还是算了,时间复杂度为O(n^2)不说,还不具有稳定性,代码长度甚至可以和优化过的快速排序一拼了也是难绷...连冒泡排序都不如...)

二、堆排序

稳定性:不稳定

时间复杂度:O(n logn)

额外空间复杂度:O(1)

堆排序的时间复杂度和快速排序一样,也是O(n logn),这是一种非常快速的排序了,并且它的额外空间复杂度为O(1),这也使得它在实际应用中也比较广泛。

📚 算法思想

堆排序的思想也是很简单的,在之前我们学习过"优先级队列",也可以分为"大根堆""小根堆"

不清楚什么是"优先级队列",不认识"大根堆","小根堆"的可以去我之前的文章中进行学习:
Java-数据结构-优先级队列(堆)_java优先级队列获取大根堆-CSDN博客
Java-数据结构-优先级队列(堆的使用)-CSDN博客
而堆排序的实现,就是以堆中的各种方法组合起来实现的:

首先,我们需要先将数组创建成一个"大根堆",这样我们就能够做到轻易地获取数组中的最大元素。

然后对这个"大根堆"的堆顶元素(最大元素)不断的放到最后,并进行删除操作(假意的删除,其实只是在后续操作中不再访问该元素),这样直到最后,我们就能得到一个升序数组。

在这个过程中,我们需要实现"创建大根堆""向下调整"的方法,而这些方法在上面两篇博客链接中也有详细的讲解,可以移步到上述两篇博客中进行学习~

图示

📖 代码示例

    public void heapSort(int[] array){
        //构造一个大根堆
        createHeap(array);
        int len = array.length;
        for(int i = len - 1;i > 0;i--){
            //将array[0]放到最后(最大的数放到最后)
            swap(array,0,i);
            //向下调整,再次变成大根堆(堆到后面的大数不再调整)
            siftDown(array,0,i);
        }
    }
    public void createHeap(int[] array){
        int index = array.length;
        //从最后一个父结点开始,依次将父结点向前进行向下调整
        for(int parent = (index - 1 - 1) / 2;parent >= 0;parent--){
            siftDown(array,parent,index);
        }
    }
    public void siftDown(int[] array,int parent,int len){
        int child = 2 * parent + 1;
        while(child < len){
            if(child + 1 < len && array[child + 1] > array[child]){
                child = child + 1;
            }
            if(array[child] > array[parent]){
                swap(array,child,parent);
                parent = child;
                child = parent * 2 + 1;
            }else {
                break;
            }
        }
    }

那么这篇关于选择排序的文章到这里就结束啦,作者能力有限,如果有哪里说的不够清楚或者不够准确,还请各位在评论区多多指出,我也会虚心学习的,我们下次再见啦

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IOTDB安装部署

IOTDB一般用于工业互联网&#xff0c;至于具体的介绍请自行搜索 1.环境准备 安装前需要保证设备上配有 JDK>1.8 的运行环境&#xff0c;并配置好 JAVA_HOME 环境变量。 设置最大文件打开数为 65535。 关闭防火墙 systemctl stop firewalld.service systemctl disable …

游戏引擎学习第100天

仓库:https://gitee.com/mrxiao_com/2d_game_2 昨天的回顾 今天的工作重点是继续进行反射计算的实现。昨天&#xff0c;我们开始了反射和环境贴图的工作&#xff0c;成功地根据法线显示了反射效果。然而&#xff0c;我们还没有实现反射向量的计算&#xff0c;导致反射交点的代…

分布式 NewSQL 数据库(TiDB)

TiDB 是一个分布式 NewSQL 数据库。它支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议&#xff0c;具有数据强一致的高可用特性&#xff0c;是一个不仅适合 OLTP 场景还适合 OLAP 场景的混合数据库。 TiDB是 PingCAP公司自主设计、研发的开源分布式关系型数据…

Vue响应式原理实现总结(数据劫持Object.defineProperty/Proxy+发布订阅者设计模式)

Vue的响应式主要分为数据劫持和发布订阅模式。Vue2用的是Object.defineProperty,而Vue3改用Proxy。数据劫持就是在访问或修改对象属性时进行拦截,然后触发相应的更新。发布订阅模式则是用来收集依赖(比如视图更新函数),当数据变化时通知这些依赖执行。 总结一下,关键点包…

以若依移动端版为基础,实现uniapp的flowable流程管理

1.前言 此代码是若依移动端版为基础&#xff0c;实现flowable流程管理&#xff0c;支持H5、APP和微信小程序三端。其中&#xff0c;APP是在安卓在雷电模拟器环境下完成的&#xff0c;其他环境未测试&#xff0c;此文章中所提及的APP均指上述环境。移动端是需要配合若依前后端分…

封装一个sqlite3动态库

作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、项目案例 二…

Qt Creator 5.0.2 (Community)用久了突然变得很卡

目录 1.现象 2.解决方案 1.现象 很久没有用Qt Creator开发项目了&#xff0c;刚刚结束的项目又是用VS2019开发的&#xff1b;这两天刚好有时间去学习一下Qt&#xff0c;刚好要用Qt Creator&#xff0c;结果一打开就没反应&#xff0c;主界面显示出来要好几分钟&#xff0c;最…

[C++]多态详解

目录 一、多态的概念 二、静态的多态 三、动态的多态 3.1多态的定义 3.2虚函数 四、虚函数的重写&#xff08;覆盖&#xff09; 4.1虚函数 4.2三同 4.3两种特殊情况 &#xff08;1&#xff09;协变 &#xff08;2&#xff09;析构函数的重写 五、C11中的final和over…

mac 意外退出移动硬盘后再次插入移动硬盘不显示怎么办

第一步&#xff1a;sudo ps aux | grep fsck 打开mac控制台输入如下指令&#xff0c;我们看到会出现两个进程&#xff0c;看进程是root的这个 sudo ps aux|grep fsck 第二步&#xff1a;杀死进程 在第一步基础上我们知道不显示u盘的进程是&#xff1a;62319&#xff0c;我们…

国家队出手!DeepSeek上线国家超算互联网平台!

目前,国家超算互联网平台已推出 DeepSeek – R1 模型的 1.5B、7B、8B、14B 版本,后续还会在近期更新 32B、70B 等版本。 DeepSeek太火爆了!在这个春节档,直接成了全民热议的话题。 DeepSeek也毫无悬念地干到了全球增速最快的AI应用。这几天,国内的云计算厂家都在支持Dee…

ElasticSearch基础和使用

ElasticSearch基础 1 初识ES相关组件 &#xff08;1&#xff09;Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。Elasticsearch结合kibana、Logstash、Beats组件 也就是elastic stack&#xff08;ELK&#xff09; 广泛应…

使用Python爬虫实时监控行业新闻案例

目录 背景环境准备请求网页数据解析网页数据定时任务综合代码使用代理IP提升稳定性运行截图与完整代码总结 在互联网时代&#xff0c;新闻的实时性和时效性变得尤为重要。很多行业、技术、商业等领域的新闻都可以为公司或者个人发展提供有价值的信息。如果你有一项需求是要实时…

vs2022支持.netframework4.0

下载nuget包 .netframework4.0 解压nuget 复制到C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 参考 https://www.cnblogs.com/bdqczhl/p/18670152 https://blog.csdn.net/xiaomeng1998_/article/details/135979884

【云安全】云原生- K8S kubeconfig 文件泄露

什么是 kubeconfig 文件&#xff1f; kubeconfig 文件是 Kubernetes 的配置文件&#xff0c;用于存储集群的访问凭证、API Server 的地址和认证信息&#xff0c;允许用户和 kubectl 等工具与 Kubernetes 集群进行交互。它通常包含多个集群的配置&#xff0c;支持通过上下文&am…

IoTDB 常见问题 QA 第五期

关于 IoTDB 的 Q & A 情人节之际&#xff0c;让 IoTDB Q&A 陪您一起共度解惑&#xff01;我们将定期汇总我们将定期汇总社区讨论频繁的问题&#xff0c;并展开进行详细回答&#xff0c;通过积累常见问题“小百科”&#xff0c;方便大家使用 IoTDB。 Q1&#xff1a;导入…

SwiftUI 5.0 中宝藏视图修改器 containerRelativeFrame 趣谈(下)

概览 小伙伴们都知道,为了将 SwiftUI 中多如牛毛的视图井然有序、有条不紊的组织起来,我们必须借助容器(Container)伏虎降龙般地威力。而如何最大限度的让容器中的子视图能根据容器尺寸安排自己的空间,则需要一些技术手段来洞幽察微。 在过去,我们往往使用 GeometryRead…

家里WiFi信号穿墙后信号太差怎么处理?

一、首先在调制解调器&#xff08;俗称&#xff1a;猫&#xff09;测试网速&#xff0c;网速达不到联系运营商&#xff1b; 二、网线影响不大&#xff0c;5类网线跑500M完全没问题&#xff1b; 三、可以在卧室增加辅助路由器&#xff08;例如小米AX系列&#xff09;90~200元区…

windows,docker停止所有容器

CMD命令窗口 你可以尝试使用以下命令来停止所有正在运行的Docker容器&#xff1a; FOR /f "tokens*" %i IN (docker ps -q) DO docker stop %i这条命令的工作原理是&#xff1a; docker ps -q 列出所有正在运行的容器的ID。 FOR /f "tokens*" %i IN (c…

Jenkins介绍

什么是Jenkins Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成和持续交付&#xff08;CI/CD&#xff09;。它帮助开发团队自动化构建、测试和部署软件&#xff0c;从而提高开发效率和软件质量。 如果一个系统是前后端分离的开发模式&#xff0c;在集成阶段会需…

解锁电商数据宝藏:淘宝商品详情API实战指南

在电商蓬勃发展的今天&#xff0c;数据已成为驱动业务增长的核心引擎。对于商家、开发者以及数据分析师而言&#xff0c;获取精准、实时的商品数据至关重要。而淘宝&#xff0c;作为国内最大的电商平台&#xff0c;其海量商品数据更是蕴含着巨大的价值。 本文将带你深入探索淘…