经典算法学习之-----直接选择排序(三)

简介: 经典算法学习之-----直接选择排序(三)

三.插入排序介绍


插入排序的基本思路是每次插入一个元素,每一趟完成对一个待排元素的放置,直到全部插入完成。


直接插入排序


直接插入排序是一种最简单的排序方法,过程就是将每个待排元素逐个插入到已经排好的有序序列中。


折半插入排序


由于在插入排序的过程中,已经生成了一个(排好的元素组成的)有序数列。所以在插入待排元素时可以使用折半查找的方式更快速的确定新元素的位置,当元素个数较多时,折半插入排序优于直接插入排序。


希尔排序

希尔排序可以看做是分组插入的排序方法,把全部元素分成几组(等距元素分到一组),在每一组内进行直接插入排序。然后继续减少间距,形成新的分组,进行排序,直到间距为1时停止。


四. 伪代码约定


伪代码是用来描述算法执行的步骤,不会具体到某一种语言,为了表达清晰和标准化,会有一些约定的含义:

缩进:表示块结构,如循环结构或选择结构,使用缩进来表示这一部分都在该结构中。

循环计数器:对于循环结构,在循环终止时,计数器的值应该为第一个超出界限的值。

to:表示循环计数器的值增加。

downto:表示循环计数器的值减少。

by:循环计数器的值默认变化量为1,当大于1时可以使用by。

变量默认是局部定义的。

数组元素访问:通过"数组名[下标]"形式,在伪代码中,下标从1开始("A[1]“代表数组A的第一个元素)。

子数组:使用”…"来代表数组中的一个范围,如"A[i…j]"代表从第i个到第j个元素组成的子数组。

对象与属性:复合的数据会被组织成对象,如链表包含后继(next)和存储的数据(data),使用“对象名 + 点 + 属性名”。

特殊值NIL:表示指针不指向任何对象,如二叉树节点无子孩子可认为左右子节点信息为NIL。

return:返回到调用过程的调用点,在伪代码中允许返回多个值。

and和or:与运算和或运算默认短路,即如果已经能够确定表达式结果时,其他条件不会去判断或执行。


五、选择排序


1. 选择排序介绍

选择排序的核心思想是:每一趟从无序区中选出关键字最小的元素,按顺序放在有序区的最后(生成新的有序区,无序区元素个数减1),直到全部排完为止。


直接选择排序

也称简单选择排序,整个过程就是每一趟都将无序区中的所有元素进行逐一比较,找到最小的元素,与无序区中的首个元素进行交换,有序区长度加1,无序区长度减1。重复以上步骤,直到所有的元素均已排好。


树形选择排序

也称锦标赛排序,是为了优化每次在无序区中确定最小元素时比较次数过多的问题。核心思想是借助树形结构对整个序列进行两两比较,将数值较小的元素作为优胜者上升到父节点。最后能够在树形结构中记录每一次优胜者之间的关系,按规则取出即可。


堆排序

堆排序是对树形选择排序的优化,由于树形选择排序需要花费较多的存储空间,堆排序的主要思想是构建一个小顶堆(升序排列中)。整个的过程就是不断的弹出堆顶元素,归入有序区,然后继续将堆中剩余元素调整为小顶堆,重复这个过程,直到排好所有元素。


2. 直接选择排序

输入

n个数的序列,通常直接存放在数组中,可能是任何顺序。


输出

输入序列的一个新排列,满足从小到大的顺序(默认讨论升序,简单的修改就可以实现降序排列)。


算法说明

直接选择排序的主要步骤是:在第1趟中,从n个记录中找出关键字最小的记录与第1个记录交换;在第2趟中,从n-1个记录中找出关键字最小的记录与第2个记录交换;可以归纳为:在第i趟中,从n-i+1个记录中找出关键字最小的记录与第i个记录交换;直到完成i=n-1时的操作,此时整个序列有序。


算法流程

如果使用直接选择排序对元素个数为n的序列进行排序,需要进行n-1趟排序。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ciQfUSPU-1659763128775)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a520c7cacf7c48cf945ddff9f32a3fe4~tplv-k3u1fbpfcp-zoom-1.image)]


第1趟:找出最小元素 5,与第1个元素38交换 -> 5,38,47,15,36,26

第2趟:找出最小元素15,与第2个元素38交换 -> 5,15,47,38,36,26

第3趟:找出最小元素26,与第3个元素47交换 -> 5,15,26,38,36,47

第4趟:找出最小元素36,与第4个元素38交换 -> 5,15,26,36,38,47

第5趟:找出最小元素38,已在对应位置无需交换 -> 5,15,26,36,38,47


3. 伪代码

for i = 1 to n - 1
    k = i
    for j = i + 1 to n
        if A[j] < A[k]
            k = j
    if k != i
        exchange A[i] with A[k]


六、算法实践


1. 算法实现

输入数据(input):11,34,20,10,12,35,41,32,43,14

Java源代码

需要注意源代码与伪代码的区别,请查看文章开头补充的概念部分,这里不做过多说明。

public class SelectSort {
    public static void main(String[] args) {
        // input data
        int[] a = {11,34,20,10,12,35,41,32,43,14};
        // 调用选择排序
        sort(a);
        // 查看排序结果
        for (int data : a){
            System.out.print(data + "\t");
        }
    }
    private static void sort(int[] a){
        // 外层循环用于控制循环的趟数
        for (int i = 0;i < a.length - 1;i++){
            int k = i;
            // 内层循环的作用是在无序区中选出最小的元素并记录
            for (int j = i + 1;j < a.length;j++){
                if (a[j] < a[k]) {
                    k = j;
                }
            }
            // 如果本轮选出的最小元素没有在对应的位置上则交换
            if (k != i){
                int tmp = a[i];
                a[i] = a[k];
                a[k] = tmp;
            }
        }
    }
}


执行效果


输出数据(output):10,11,12,14,20,32,34,35,41,43


2. 时间复杂度

了解了算法的核心思想后可以发现,整体的排序趟数(外循环)与每趟排序中的元素比较次数(内循环)均和序列的初始顺序无关,因此时间复杂度T(n)= n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1)=O( n 2 n^{2} n2) 。


3. 空间复杂度

算法在执行过程中只需要定义的几个临时变量,所以空间复杂度为常数级:O(1) 。

相关文章
|
5天前
|
算法 JavaScript 前端开发
第一个算法项目 | JS实现并查集迷宫算法Demo学习
本文是关于使用JavaScript实现并查集迷宫算法的中国象棋demo的学习记录,包括项目运行方法、知识点梳理、代码赏析以及相关CSS样式表文件的介绍。
第一个算法项目 | JS实现并查集迷宫算法Demo学习
|
9天前
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
15 2
|
2月前
|
机器学习/深度学习 人工智能 资源调度
【博士每天一篇文献-算法】连续学习算法之HAT: Overcoming catastrophic forgetting with hard attention to the task
本文介绍了一种名为Hard Attention to the Task (HAT)的连续学习算法,通过学习几乎二值的注意力向量来克服灾难性遗忘问题,同时不影响当前任务的学习,并通过实验验证了其在减少遗忘方面的有效性。
49 12
|
2月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
2月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
2月前
|
搜索推荐 算法 Java
经典排序算法之-----选择排序(Java实现)
这篇文章通过Java代码示例详细解释了选择排序算法的实现过程,包括算法的基本思想、核心代码、辅助函数以及测试结果,展示了如何通过选择排序对数组进行升序排列。
经典排序算法之-----选择排序(Java实现)
|
2月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之HNet:Continual learning with hypernetworks
本文提出了一种基于任务条件超网络(Hypernetworks)的持续学习模型,通过超网络生成目标网络权重并结合正则化技术减少灾难性遗忘,实现有效的任务顺序学习与长期记忆保持。
34 4
|
2月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之RWalk:Riemannian Walk for Incremental Learning Understanding
RWalk算法是一种增量学习框架,通过结合EWC++和修改版的Path Integral算法,并采用不同的采样策略存储先前任务的代表性子集,以量化和平衡遗忘和固执,实现在学习新任务的同时保留旧任务的知识。
74 3
|
2月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-综述】基于脑启发的连续学习算法有哪些?附思维导图
这篇博客文章总结了连续学习的分类,包括经典方法(重放、正则化和稀疏化方法)和脑启发方法(突触启发、双系统启发、睡眠启发和模块化启发方法),并讨论了它们在解决灾难性遗忘问题上的优势和局限性。
29 2
|
3月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
108 9
下一篇
无影云桌面