【蓝桥杯-筑基篇】排序算法

🍓系列专栏:蓝桥杯

🍉个人主页:个人主页

目录

前言:

一、冒泡排序

二、选择排序

三、插入排序

四、图书推荐


前言:

算法工具推荐:

 还在为数据结构发愁吗?这款可视化工具,帮助你更好的了解其数据结构数据结构和算法动态可视化 (Chinese) - VisuAlgo

一、冒泡排序

1.什么是冒泡排序?

冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向 上冒。

思想:

我们要把相邻的元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置;当一个元素小于右侧相邻元素时,位置不变

动图演示:


 

                                      

2.冒泡排序代码实现

 代码1:

import java.util.Arrays;

public class bubble {
    public static void main(String[] args) {
        int arr[]={5,8,6,3,9,2,1,7};
        System.out.println("排序前:"+Arrays.toString(arr));
        BubbleSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }

    private static void BubbleSort(int[] arr) {
        int temp=0; //临时存储变量
        int n=0; //统计排序次数


        for (int i = 1; i < arr.length; i++) {
            n++;
            for (int j = 0; j < arr.length-i; j++) {

                if (arr[j]>arr[j+1]){
                    temp=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=temp;


                }

            }
            System.out.println("第"+n+"轮:"+Arrays.toString(arr));
        }
    }


}

 3.冒泡排序代码优化

优化:
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。

代码2(第一次优化):

import java.util.Arrays;

public class bubble {
    public static void main(String[] args) {
        int arr[]={5,8,6,3,9,2,1,7};
        System.out.println("排序前:"+Arrays.toString(arr));
        BubbleSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }

    private static void BubbleSort(int[] arr) {
        int temp=0; //临时存储变量
        int n=0; //统计排序次数

        for (int i = 1; i < arr.length; i++) {
            n++;
            boolean flag=true;

            for (int j = 0; j < arr.length-i; j++) {


                if (arr[j]>arr[j+1]){
                    temp=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=temp;
                    flag=false;


                }

            }
            if (flag==true){
                break;
            }

            System.out.println("第"+n+"轮:"+Arrays.toString(arr));
        }
    }


}

与第1版代码相比,第2版代码做了小小的改动,利用布尔变量flag作为标记。如果在本轮排序中,元素有交换,则说明数列无序;如果没有元素交换,则说明数列已然有序,然后直接跳出大循环。

这只是冒泡序优化的第一步,我们还可以进一步来提开它的性能。为了说明问题,这次以一个新的数列为例。

为了说明问题,这次以一个新的数列为例

arr={3,4,2,1,5,6,7,8}

import java.util.Arrays;

public class bubble {
    public static void main(String[] args) {
        int arr[]={3,4,2,1,5,6,7,8};
        System.out.println("排序前:"+Arrays.toString(arr));
        BubbleSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }

    private static void BubbleSort(int[] arr) {
        int temp=0; //临时存储变量
        int n=0; //统计排序次数

        for (int i = 1; i < arr.length; i++) {
            n++;
            boolean flag=true;

            for (int j = 0; j < arr.length-i; j++) {
                System.out.println("排序:"+Arrays.toString(arr));

                if (arr[j]>arr[j+1]){
                    temp=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=temp;
                    flag=false;


                }

            }
            if (flag==true){
                break;
            }

            System.out.println("第"+n+"轮:"+Arrays.toString(arr));
        }
    }


}

 第一轮中:

元素4和5比较,发现4小于5,所以位置不变。

元素5和6比较,发现5小于6,所以位置不变。

元素6和7比较,发现6小于7,所以位置不变。

元素7和8比较,发现7小于8,所以位置不变。
 

第二轮中:

元素3和4比较,发现3小于4,所以位置不变。

元素4和5比较,发现4小于5,所以位置不变。

元素5和6比较,发现5小于6,所位位置不变。

元素6和7比较,发现6小于7,所以位置不变。

元素7和8比较,发现7小于8,所以位置不变。

.................................................................

按照现有的逻辑,有序区的长度和排序的轮数是相等的。例如第1轮排序过后的有序区长度是1,第2轮排序过后的有序区长度是2....

实际上,数列真正的有序区可能会大于这个长度,如上述例子中在第2轮排序时,后面的5个元素实际上都已经属于有序区了。因此后面的多次元素比较是没有意义的。

那么,该如何避免这种情况呢?我们可以在每一轮排序后, 记录下来最后一次元素交换的位置,该位置即为无序数列的边界,再往后就是有序区了。

 4.冒泡排序代码再次优化

代码3:

import java.util.Arrays;

public class bubble {
    public static void main(String[] args) {
        int arr[]={3,4,2,1,5,6,7,8};
        System.out.println("排序前:"+Arrays.toString(arr));
        BubbleSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }

    private static void BubbleSort(int[] arr) {
        int temp=0; //临时存储变量
        int n=0; //统计排序次数
        int lastIndex= 0;//记录最后一次交换的位置
        int sortBorder= arr.length-1;//无序数列的边界

        for (int i = 1; i < arr.length; i++) {
            n++;
            boolean flag=true;

            for (int j = 0; j < sortBorder; j++) {
                System.out.println("排序:"+Arrays.toString(arr));

                if (arr[j]>arr[j+1]){
                    temp=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=temp;
                    lastIndex=j;
                    flag=false;


                }

            }
            sortBorder=lastIndex;
            if (flag==true){
                break;
            }

            System.out.println("第"+n+"轮:"+Arrays.toString(arr));
        }
    }


}


 

二、选择排序

基本介绍:

选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。

思想:

选择排序 (select sorting) 也是一种简单的排序方法。它的基本思想是: 第一次从 arr[0]~arr[n-1]中选取最小值,与arr[0]交换,第二次从 ar[1]~arr[n-1]中选取最小值,与 arr[1]交换,第三次从 ar[2]~arr[n-1]中选取最小值,与 arr[2]交换,.................,第 i 次从arr[i-1]~arr[n-1]中选取最小值,与 arr[i-1]交换,.............,第n-1 次从arr[n-2] ~ arr [n-1]中选取最小值,与 arr[n-2]交换,总共通过 n-1 次,得到一个按排序码从小到大排列的有序序列。

1.选择排序

    //普通选择排序
    public static void sort1(int[] array){
        int count = 0;//统计运行次数
        int cnt = 0; //交换次数
        for(int i=0;i<array.length-1;i++) {
            int min=array[i];
            int minIndex=i;
            count++;
            for(int j=i+1;j<array.length;j++){
                if(min>array[j]) {
                    min=array[j];
                    minIndex=j;
                }
            }
            if(minIndex!=i){
                cnt++;
                array[minIndex]=array[i];
                array[i]=min;
            }
 
 
        }
        System.out.println(Arrays.toString(array));
        System.out.println("运行次数:"+count+"次  交换次数:"+cnt);
 
    }

2.优化版

 
import java.util.Arrays;
import java.util.Random;
 
/**
 * 选择排序优化
 */
class SelectionSort2 {
    public static void main(String[] args) {
        //产生一个随机数组
        Random r = new Random();
        int arr[] = new int[2000];
        for(int i=0;i<arr.length;i++){
            arr[i] =r.nextInt(1000);
        }
 
//因为本优化版本每次循环找出最大以及最小值,所以执行执行:arr.length/2
        int ArrLength = (arr.length/2);
        int  temp1,temp2;
        long count = 0;
        //记录开始时间
        long startStamp = System.currentTimeMillis();
        //算法开始
        for(int j=0;j<ArrLength;j++){
            int minIndex = j;
            int maxIndex= j;
            for(int i=j;i<arr.length-j;i++){
                if (arr[minIndex] > arr[i]) {
                    minIndex = i;
                }
                if (arr[maxIndex] < arr[i]) {
                    maxIndex= i;
                }
                count++;
            }
            temp1  = arr[minIndex];
            arr[minIndex] = arr[j];
            arr[j] = temp1;
 
            if(j!=maxIndex) {	//maxIndex不能再原本的minIndex位置上
                temp2 = arr[maxIndex];
                arr[maxIndex] = arr[arr.length - j - 1];
            }else{
                temp2 = arr[minIndex];
                arr[minIndex] = arr[arr.length - j - 1];
            }
            arr[arr.length - j - 1] = temp2;
        }
        //计算算法结束时间
        long endStamp = System.currentTimeMillis();
        System.out.println("用时总长:"+(endStamp-startStamp));
        System.out.println("循环次数:"+count);
 
 
        System.out.println(Arrays.toString(arr));
    }
}

三、插入排序

插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n -1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

Java实现插入排序的代码如下:

public static void insertionSort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

上面的代码使用了两重循环,外层循环枚举未排序部分的元素,内层循环在已排序部分中找到适当的位置并进行插入。

这段代码的时间复杂度为O(n^2),空间复杂度为O(1)。

四、图书推荐

《经典算法的起源》是一本计算机算法方面的科普性书籍,作者以通俗易懂、引人入胜的叙述方式介绍各种算法思想,避免使用一些过于严谨的专业术语。比如,用“大海捞针”来形容一种搜索算法就非常形象,顾名思义,广大读者更容易理解该搜索策略。本书适合对计算机知识有兴趣的初中生、高中生或其他相关人员阅读。计算机专业一、二年级的大学生阅读此书,也会对相关知识的起源有深刻的印象。

本书的目的是向非专业人士介绍算法,使读者理解算法如何运作,而不是阐述算法在生活中的作用。有些书籍在某些方面做了杰出工作,如介绍如何改善大数据的处理,讨论将人工智能和计算设备融入日常生活对人类生存条件的改变。本书对“发生什么”不感兴趣,对“如何发生”感兴趣。为此,本书给出一些真实的算法,不仅描述它们做什么,更重要的是关注它们如何运作。本书将提供详细的解释说明,而非粗略的介绍。

 

 本书由机械工业出版社提供

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

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

相关文章

列表排序-第14届蓝桥杯STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第108讲。 蓝桥杯选拔赛现已更名为STEMA&#xff0c;即STEM 能力测试&#xff0c;是蓝桥杯大赛组委会与美国普林斯顿多…

Request和Response的概述

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章⭐作者主页&#xff1a;︶ㄣ释然⭐如果觉得文章写的不错&#xff0c;欢迎点个关注&#x1f609;有写的不好的地方也欢迎指正&#xff0c;一同进步&#x1f601;Request和Respo…

UE笔记-AI Move To无法正常结束/打断 1

启用Stop on Overlap 会导致AI与目标距离受到碰撞影响&#xff0c;实际效果需按要求处理 当Lock AILogic为True时&#xff0c;Move To的Task无法被黑板装饰器打断 当Use Continuos Goal Tracking为True时&#xff0c;Move To的节点不会根据Acceptance Radius设定而结束&#x…

第五周作业、第一次作业(1.5个小时)、练习一

一、创建servlet的过程没有太多好说的&#xff0c;唯一需要注意的就是&#xff1a;旧版本的servlet确实需要手动配置web.xml文件&#xff0c;但是servlet2.5以后,servlet的配置直接在Java代码中进行注解配置。我用的版本就不再需要手动去配置web.xml文件了&#xff0c;所以我只…

Spring Cloud Alibaba 微服务2,注册中心演变 + Nacos注册中心与配置中心

目录专栏导读一、什么是Nacos&#xff1f;二、注册中心演变及其设计思想1、RestTemplate调用远程服务2、通过Nginx维护服务列表&#xff08;upStream&#xff09;3、通过Nacos实现注册中心4、心跳版Nacos三、Nacos Discovery四、Nacos核心功能1、服务注册2、服务心跳3、服务同步…

Python的30个编程技巧

1. 原地交换两个数字 Python 提供了一个直观的在一行代码中赋值与交换&#xff08;变量值&#xff09;的方法&#xff0c;请参见下面的示例&#xff1a; x,y 10,20 print(x,y) x,y y,x print(x,y) #1 (10, 20) #2 (20, 10) 赋值的右侧形成了一个新的元组&#xff0c;左侧立即解…

Kubernetes详细安装

By&#xff1a;雪月三十 参考&#xff1a; https://blog.csdn.net/qq_43580215/article/details/125153959 https://juejin.cn/post/6844903943051411469 https://mp.weixin.qq.com/s?__bizMzI0MDQ4MTM5NQ&mid2247502359&idx1&sn8c16100c9731359b9864403183f44233…

python 正则使用详解

python 正则使用详解什么是正则在 python 中使用正则一些正则的定义python 正则的方法match 从字符串开头匹配正则返回的结果分析&#xff08;重要&#xff09;fullmatch 严格匹配整个字符串search 任意位置开始匹配sub 替换匹配内容subn 以元组方式返回替换结果split 正则切割…

一 Go环境搭建

1. 下载地址 https://golang.google.cn/dl/ 傻瓜式安装&#xff0c;自动会配置path的变量&#xff0c;安装完成后可以使用go version 查看当前安装的版本 本文使用目前最新的1.20.2版本 2. 配置go环境 cmd控制栏打开输入以下命令&#xff08;如果cmd有问题可以尝试powershe…

面试了一个32岁的程序员,一个细节就看出来是培训班的····

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

Qt(c++)调用海康威视监控摄像头

文章目录一.海康威视监控摄像头开发SDK介绍二.海康SDK模块说明三.Qt项目中海康威视SDK配置四.实时预览摄像头图像程序一.海康威视监控摄像头开发SDK介绍 设备网络SDK是基于设备私有网络通信协议开发的&#xff0c;为嵌入式网络硬盘录像机、NVR、网络摄像机、网络球机、视频服务…

【Linux】冯诺依曼体系结构

冯诺依曼体系结构一、计算机结构体系来源二、冯诺依曼体系结构三、冯诺依曼体系结构中的数据流动一、计算机结构体系来源 研制电子计算机的想法产生于第二次世界大战期间&#xff0c;主要用来进行弹道计算&#xff0c;在"时间就是胜利"的战争年代&#xff0c;迫切需…

【JavaEE进阶篇1】认识Spring、认识IoC、使用spring创建对象

目录 一、什么是Spring 1.1容器 1.2什么是IoC 传统方式创建对象的问题&#xff1a; 类与类之间的耦合性过大 Ioc的优点 Spring IoC容器最核心的功能 1.3DI概念说明(Dependency Injection) IoC和DI的区别是什么 二、Spring项目的创建 三、Spring的使用(把对象存储到spr…

ChatGPT是如何训练得到的?通俗讲解

首先声明喔&#xff0c;我是没有任何人工智能基础的小白&#xff0c;不会涉及算法和底层原理。 我依照我自己的简易理解&#xff0c;总结出了ChatGPT是怎么训练得到的&#xff0c;非计算机专业的同学也应该能看懂。看完后训练自己的min-ChatGPT应该没问题 希望大牛如果看到这…

stm32外设-中断详解

0. 写在最前 本栏目笔记都是基于stm32F10x 1. 中断是啥&#xff1f; 什么是中断&#xff1a;CPU在处理某一事件A时&#xff0c;发生的另外某一事件B请求CPU去处理&#xff08;产生了中断&#xff09;&#xff0c;随后CPU暂时中断当前正在执行的任务&#xff0c;去对事件B进行处…

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构&#xff0c;数组虽然查找快&#xff08;有序数组可以通过二分法查找&#xff09;&#xff0c;但是插入和删除是比较慢的&#xff1b;而链表&#xff0c;插入和删除很快&#xff08;只需要改变一些引用值&#xff09;&#xff0c;但是查找就很慢&…

【C#】组件化开发,调用dll组件方法

系列文章 C#项目–业务单据号生成器&#xff08;定义规则、自动编号、流水号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 C#项目–开始日期结束日期范围计算&#xff08;上周、本周、明年、前年等&#xff09; 本文链接&…

快排函数 -- qsort函数(Quick Sort)

文章目录&#x1f50e;1.qsort函数简介&#x1f4a1;1.1.函数原型&#x1f4a1;1.2.参数含义&#x1f50e;2.比较函数介绍&#x1f50e;3.比较函数使用案例&#x1f4a1;3.1.整型数组&#x1f4a1;3.2.浮点型数组&#x1f4a1;3.3.结构体类型 - 字符串&#x1f50e;4.利用冒泡排…

震撼,支持多模态模型的ChatGPT 4.0发布了

最近几个月&#xff0c;互联网和科技圈几乎ChatGPT刷屏了&#xff0c;各种关于ChatGPT的概念和应用的帖子也是围绕在周围。当去年年底ChatGPT发布的那几天&#xff0c;ChatGPT确实震撼到了所有人&#xff0c;原来AI还可以这么玩&#xff0c;并且对国内的那些所谓的人工智能公司…

Tesla都使用什么编程语言?

作者 | 初光 出品 | 车端 备注 | 转载请阅读文中版权声明 知圈 | 进“汽车电子与AutoSAR开发”群&#xff0c;请加微“cloud2sunshine” 总目录链接>> AutoSAR入门和实战系列总目录 带着对更美好未来的愿景&#xff0c;特斯拉不仅成为有史以来最有价值的汽车公司&…