java实现排序算法(上)

news2025/1/19 11:30:05

排序算法

冒泡排序

时间和空间复杂度

要点

  • 每轮冒泡不断地比较比较相邻的两个元素,如果它们是逆序的,则需要交换它们的位置
  • 下一轮冒泡,可以调整未排序的右边界,减少不必要比较

代码

public static int[] test(int[] array) {
    // 外层循环控制遍历次数
    for (int i = 0; i < array.length; i++) {
        // 内层循环控制每轮比较和交换
        for (int j = 0; j < array.length - i - 1; j++) {
            // 比较相邻两元素大小
            if (array[j] > array[j + 1]) {
                // 交换元素位置
                int temp = array[j + 1];
                array[j + 1] = array[j];
                array[j] = temp;
            }
        }
    }
    // 返回排序后的数组
    return array;
}

测试结果

public static void main(String[] args) {
        int[] array = {3,1,2,4,7,9};
        int[] ary = test(array);
        System.out.println(Arrays.toString(ary));
    }

选择排序

时间和空间复杂度

要点

  • 每一轮选择,找出最大(最小)的元素,并把它交换到合适的位置

代码

public static int[] test(int[] array) {
        // 外循环遍历数组元素
        for (int i = 0; i < array.length; i++) {
            // 内循环从当前元素的下一个元素开始比较
            for (int j = i+1; j < array.length; j++) {
                // 如果前一个元素大于后一个元素,交换它们的位置
                if(array[i] > array[j]){
                    int temp = array[j];
                    array[j] = array[i];
                    array[i] = temp;
                }
            }
        }
        // 返回排序后的数组
        return array;
    }

测试结果

public static void main(String[] args) {
        int[] array = {3,1,2,4,7,9};
        int[] ary = test(array);
        System.out.println(Arrays.toString(ary));
    }

堆排序

时间和空间复杂度

要点(如果这里看不懂的话,是需要去了解大顶堆这个数据结构的)

  • 建立大顶堆
  • 每次将堆顶元素最大值,交换到末尾,调整堆顶元素,让它重新符合大顶堆特性

代码

import java.util.Arrays;

public class Heap {
    int[] array; // 存储堆元素的数组
    int size;    // 堆的大小

    public Heap(int capacity) {
        this.array = new int[capacity];
    }

    public Heap(int[] array){
        this.array = array;
        this.size = array.length;
        heapify(); // 调用堆化方法,构建堆
    }

    /**
     * 建立堆
     */
    private void heapify() {
        // 建立堆的过程实际上是找到最后一个非叶子节点
        for (int i = size/2-1; i >=0 ; i--) {
            // 接下来的循环中,i 是当前非叶子节点的索引
            down(i); // 对当前非叶子节点进行下潜操作,保证满足堆的性质
        }
    }

    // 下潜操作
    private void down(int i) {
        int left = i * 2 + 1; // 左子节点索引
        int right = left + 1; // 右子节点索引
        int max = i;          // 初始化最大值索引为当前节点

        // 判断左子节点是否存在且大于当前节点
        if (left < size && array[left] > array[max]) {
            max = left;
        }
        // 判断右子节点是否存在且大于当前节点
        if (right < size && array[right] > array[max]) {
            max = right;
        }

        if (max != i) {
            // 交换当前节点与最大值节点
            swap(max, i);
            // 递归调用下潜操作,保证交换后的子树仍然满足堆的性质
            down(max);
        }
    }

    // 交换数组中两个位置的元素
    private void swap(int a, int b) {
        int temp = array[a];
        array[a] = array[b];
        array[b] = temp;
    }
}

public static void main(String[] args) {
    int[] array = {1,2,3,4,5,6,7};
    Heap heap = new Heap(array);
    
    // 堆排序
    while (heap.size > 1) {
        // 将堆顶元素与堆尾元素交换
        heap.swap(0, heap.size - 1);
        // 堆大小减一
        heap.size--;
        // 对交换后的堆顶元素进行下潜操作,保证仍然满足堆的性质
        heap.down(0);
    }
    
    System.out.println(Arrays.toString(heap.array));
}

测试结果

插入排序

时间和空间复杂度

要点

  • 将数组分为两部分[0----low-1][low----a.length-1]
    • 左边[0-----low-1]是已排序部分
    • 右边[low------a.length-1]是未排序部分
  • 每次从未排序区域取出low位置的元素,插入到已排序区域

代码

  

public static int[] test(int[] array) {
        // 外层循环,从数组第二个元素开始
        for (int low = 1; low < array.length; low++) {
            // 记录当前元素值
            int t = array[low];
            // 从当前元素的前一个位置开始向前查找插入位置
            int i = low - 1;
            while (i >= 0 && t < array[i]) {
                // 如果当前元素小于已排序元素,将已排序元素后移一位
                array[i + 1] = array[i];
                i--;
            }
            // 找到插入位置,将当前元素插入
            if (i != low - 1) {
                array[i + 1] = t;
            }
        }
        // 返回排序后的数组
        return array;
    }

测试结果

public static void main(String[] args) {
        int[] array = {3,1,2,4,7,9};
        int[] ary = test(array);
        System.out.println(Arrays.toString(ary));
    }

希尔排序

时间和空间复杂度

要点

  • 简单来说,就是分组实现插入,魅族元素间隙称为hap
  • 每轮排序之后gap逐渐变小,直到gap为1完成排序
  • 对插入排序的优化,让元素更快地交换到最终位置

代码

public static int[] test(int[] array) {
        // 此时的gap就是间隙
        for (int gap = array.length >> 1; gap >= 1 ; gap = gap >> 1) {
            for (int low = gap; low < array.length ; low++) {
                // 记录当前位置的元素值
                int t = array[low];
                // 初始化比较位置为当前位置的前一个位置
                int i = low - gap;
                // 当比较位置合法且当前元素值小于比较位置的元素值时进行插入排序
                while (i >= 0 && t < array[i]){
                    // 将比较位置的元素往后移动gap个位置
                    array[i + gap] = array[i];
                    // 更新比较位置为前一个gap位置
                    i -= gap;
                }
                // 如果实际插入位置不是当前位置的前一个gap位置,则进行插入操作
                if (i != low - gap){
                    array[i + gap] = t;
                }
            }
        }
        // 返回排序后的数组
        return array;
    }

测试结果

public static void main(String[] args) {
        int[] array = {3,1,2,4,7,9};
        int[] ary = test(array);
        System.out.println(Arrays.toString(ary));
    }

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

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

相关文章

政安晨:【完全零基础】认知人工智能(二)【超级简单】的【机器学习神经网络】—— 底层算法

如果小伙伴第一次看到这篇文章&#xff0c;可以先浏览一下我这个系列的上一篇文章&#xff1a; 政安晨&#xff1a;【完全零基础】认知人工智能&#xff08;一&#xff09;【超级简单】的【机器学习神经网络】 —— 预测机https://blog.csdn.net/snowdenkeke/article/details/…

mac东西拷不进硬盘怎么回事 mac东西拷不进硬盘怎么办 mac硬盘读不出来怎么解决 mac拷贝不了东西到u盘

有时候我们在使用mac的过程中&#xff0c;可能会遇到一些问题&#xff0c;比如mac东西拷不进硬盘。这是一种很常见的情况&#xff0c;但是会影响我们的工作和生活。那么&#xff0c;mac东西拷不进硬盘是怎么回事呢&#xff1f;mac东西拷不进硬盘又该怎么办呢&#xff1f;本文将…

【设计模式】4、策略模式

文章目录 一、问题二、解决方案2.1 真实世界的类比2.2 策略模式结构2.3 适用场景2.4 实现方式2.5 优缺点2.6 与其他模式的关系 三、示例代码3.1 go3.2 rust 策略模式是一种行为设计模式&#xff0c;它能定义一系列算法&#xff0c;把每种算法分别放入独立的类中&#xff0c;以是…

《隐私计算简易速速上手小册》第4章:技术挑战与解决方案(2024 最新版)

文章目录 4.1 隐私计算中的技术难题4.1.1 基础知识4.1.2 重点案例:同态加密在金融数据分析中的应用4.1.3 拓展案例 1:安全多方计算在医疗数据共享中的应用4.1.4 拓展案例 2:差分隐私在社交媒体分析中的应用4.2 数据加密与解密的挑战4.2.1 基础知识4.2.2 重点案例:加密的在线…

防止被恶意调用API接口

前言 在面试时&#xff0c;经常会被问一个问题&#xff1a;如何防止别人恶意刷接口&#xff1f; 这是一个非常有意思的问题&#xff0c;防范措施挺多的。今天这篇文章专门跟大家一起聊聊&#xff0c;希望对你会有所帮助。 1 防火墙 防火墙是网络安全中最基本的安全设备之一&…

DAP下载程序(在MDK上配置DAP)以及程序调试(Keil uVision5软件的使用)

目录 1. 在MDK上配置DAP 2. 了解不同开发板不同的下载算法 3. DAP调试程序 3.1 JTAG/SWD调试原理概述 3.2 基础执行控制按钮 3.3 查看程序段/函数执行时间 3.4 结束仿真报错解决方法 3.5 工具栏常用窗口按钮介绍 3.5.1 Call Stack窗口&#xff1a;查看函数调…

【激光SLAM】激光的前端配准算法

文章目录 ICP匹配方法&#xff08;Point to Point&#xff09;PL-ICP匹配方法&#xff08;Point to Line&#xff09;基于优化的匹配方法&#xff08;Optimization-based Method&#xff09;优化方法的求解地图双线性插值拉格朗日插值法——一维线性插值 相关方法&#xff08;C…

HCIP-MGRE实验配置、PPP的PAP认证与CHAP认证、MGRE、GRE网络搭建、NAT

实验要求 R5为ISP,只能进行IP地址配素&#xff0c;其所有地址均为公有IP地址R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方 R2与R5之间使用PPP的chap认证&#xff0c;R5为主认证方 R3与R5之间使用HDLC封装。R1/R2/R3构建一个MGRE环境&#xff0c;R1为中心站点;R1、R4间为…

深入解析Android AIDL:实现跨进程通信的利器

深入解析Android AIDL&#xff1a;实现跨进程通信的利器 1. 介绍Android AIDL Android Interface Definition Language (AIDL) 是一种Android系统中的跨进程通信机制。AIDL允许一个应用程序的组件与另一个应用程序的组件通信&#xff0c;并在两者之间传输数据。 AIDL的主要作…

2024 VNCTF----misc---sqlshark sql盲注+流量分析

流量分析 wireshark 可以看到很多 any/**/Or/**/(iF(((((Ord(sUbstr((sElect(grOup_cOncat(password))frOm(users)) frOm 1 fOr 1))))in(80))),1,0))# P any/**/Or/**/(iF(((((Ord(sUbstr((sElect(grOup_cOncat(password))frOm(users)) frOm 1 fOr 1))))in(104))),1,0))#…

我的NPI项目之Android Camera (二) -- 核心部件之 Camera Sensor

说到Camera模组&#xff0c;我们比较关心的是用的什么样的sensor&#xff1f; sensor的分辨率多少&#xff0c;sensor的像素多大&#xff0c;sensor是哪家生产的等等一些问题。今天&#xff0c;我们就穿越时间&#xff0c;将sensor的历史扒一扒。 Wikipedia先看一下&#xff1…

初识 Rust 语言

目录 前言一、Rust 的背景二、Rust的特性三、部署开发环境&#xff0c;编写一个简单demo1、在ubuntu 20.04部署环境2、编写demo测试 四、如何看待Linux内核引入Rust 前言 自Linux 6.1起&#xff0c;初始的Rust基础设施被添加到Linux内核中。此后为了使内核驱动程序能够用Rust编…

C++--Linux基础使用

文章目录 几个简单命令开机关机重启查看当前目录切换当前目录列出当前目录下的目录和文件列出指定目录下的目录和文件清屏查看/设置时间 目录和文件目录概要目录详细说明相对路径和绝对路径 上古神器vi创建/打开文件vi 的两种模式vi 的常用命令 用户管理组管理用户管理修改用户…

小迪安全25WEB 攻防-通用漏洞SQL 读写注入MYSQLMSSQLPostgreSQL

#知识点&#xff1a; 1、SQL 注入-MYSQL 数据库 2、SQL 注入-MSSQL(SQL server) 数据库 3、SQL 注入-PostgreSQL 数据库 #详细点&#xff1a; Access 无高权限注入点-只能猜解&#xff0c;还是暴力猜解 因为access的数据库是独立存在的&#xff0c;不存在统一管理 …

应用回归分析:多重共线性

多重共线性的概念 在回归分析中&#xff0c;我们通常关注的是如何利用一个或多个自变量&#xff08;解释变量&#xff09;来预测一个因变量&#xff08;响应变量&#xff09;。当我们使用多元线性回归模型时&#xff0c;理想的情况是模型中的每一个自变量都能提供独特的、对因…

Cesium 问题——加载 gltf 格式的模型之后太小,如何让相机视角拉近

文章目录 问题分析问题 刚加载的模型太小,如何拉近视角放大 分析 在这里有两种方式进行拉近视角, 一种是点击复位进行视角拉近一种是刚加载就直接拉近视角// 模型三加载 this.damModel = new Cesium.Entity({name: "gltf模型",position:</

5、Linux 常用指令

一、帮助指令 1.man 指令 语法 man [命令或配置文件] //功能描述&#xff1a;获得帮助手册上的信息查看 ls 命令的帮助信息 man ls信息作用NAME命令名称SYNOPSIS如何使用命令DESCRIPTION描述命令SEE ALSO相关的手册 2.help 指令 语法 help [命令] //功能描述&#xff1a;获得…

AttributeError: module ‘distutils‘ has no attribute ‘version‘

报错 AttributeError: module ‘distutils’ has no attribute ‘version’ 出现如下图报错&#xff1a; 或者可以通过修改torch版本和固定setuptools版本为59.5.0解决&#xff0c;但是我觉得前者有点麻烦&#xff0c;后者尝试无效&#xff0c;于是找到下图路径中的文件__init…

洛谷 P1019 [NOIP2000 提高组] 单词接龙

参考代码 #include <bits/stdc.h> using namespace std; string s[25]; int vis[25], ans, now 1, n; void dfs(int k) { ans max(ans, now); for(int i 1; i < n; i) if(vis[i] < 2) { for(int j 0; j < s[k].length(); j) …

N叉树的前序遍历

1.题目 这道题是2024-2-18的签到题&#xff0c;题目难度为简单。 考察的知识点为DFS算法&#xff08;树的前序遍历&#xff09;。 题目链接&#xff1a;N叉树的前序遍历 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历…